mirror of
https://github.com/retailcrm/url-validator.git
synced 2024-11-21 20:56:07 +03:00
Init (#1)
This commit is contained in:
parent
4169bc254c
commit
59b034425f
15
.editorconfig
Normal file
15
.editorconfig
Normal file
@ -0,0 +1,15 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{less,css,yml,json}]
|
||||
indent_size = 2
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
38
.github/workflows/ci.yml
vendored
Normal file
38
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '**'
|
||||
tags-ignore:
|
||||
- '*.*'
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: "PHPUnit"
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
php-version: ['7.3', '7.4']
|
||||
steps:
|
||||
- name: Check out code into the workspace
|
||||
uses: actions/checkout@v2
|
||||
- name: Setup PHP ${{ matrix.php-version }}
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-version }}
|
||||
coverage: pcov
|
||||
- name: Composer cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ env.HOME }}/.composer/cache
|
||||
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
|
||||
- name: Install dependencies
|
||||
run: composer install -o
|
||||
- name: Configure matchers
|
||||
uses: mheap/phpunit-matcher-action@v1
|
||||
- name: Run tests
|
||||
run: composer run-script phpunit-ci
|
||||
- name: Coverage
|
||||
run: bash <(curl -s https://codecov.io/bash)
|
42
.github/workflows/code_quality.yml
vendored
Normal file
42
.github/workflows/code_quality.yml
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
name: "Code Quality Check"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "**.php"
|
||||
- "phpcs.xml"
|
||||
- ".github/workflows/code_quality.yml"
|
||||
|
||||
jobs:
|
||||
phpcs:
|
||||
name: "PHP CodeSniffer"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code into the workspace
|
||||
uses: actions/checkout@v2
|
||||
- name: Run PHPCS
|
||||
uses: chekalsky/phpcs-action@v1
|
||||
phpmd:
|
||||
name: "PHP MessDetector"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code into the workspace
|
||||
uses: actions/checkout@v2
|
||||
- name: Run PHPMD
|
||||
uses: GeneaLabs/action-reviewdog-phpmd@1.0.0
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
level: 'warning'
|
||||
reporter: github-pr-check
|
||||
standard: './phpmd.xml'
|
||||
target_directory: 'src'
|
||||
phpstan:
|
||||
name: PHPStan
|
||||
runs-on: ubuntu-18.04
|
||||
steps:
|
||||
- name: Check out code into the workspace
|
||||
uses: actions/checkout@v2
|
||||
- name: Run PHPStan
|
||||
uses: docker://oskarstark/phpstan-ga:0.12.88
|
||||
with:
|
||||
args: analyse src -c phpstan.neon --memory-limit=1G --no-progress
|
21
.gitignore
vendored
Normal file
21
.gitignore
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
# Composer files.
|
||||
/vendor
|
||||
composer.lock
|
||||
composer.phar
|
||||
|
||||
# Code Quality tools artifacts.
|
||||
coverage.xml
|
||||
test-report.xml
|
||||
phpunit.xml
|
||||
.php_cs.cache
|
||||
.phpunit.result.cache
|
||||
|
||||
# Different environment-related files.
|
||||
.idea
|
||||
.DS_Store
|
||||
.settings
|
||||
.buildpath
|
||||
.project
|
||||
.swp
|
||||
/nbproject
|
||||
.env
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2021 RetailDriver LLC
|
||||
|
||||
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 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.
|
53
composer.json
Normal file
53
composer.json
Normal file
@ -0,0 +1,53 @@
|
||||
{
|
||||
"name": "retailcrm/validator",
|
||||
"description": "Validator for symfony projects",
|
||||
"type": "library",
|
||||
"keywords": ["Validator", "RetailCRM"],
|
||||
"homepage": "https://www.retailcrm.ru/",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "RetailCRM",
|
||||
"email": "support@retailcrm.ru"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.3",
|
||||
"ext-json": "*",
|
||||
"symfony/validator": "^5.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.5.7",
|
||||
"squizlabs/php_codesniffer": "3.*",
|
||||
"phpstan/phpstan": "^0.12.92",
|
||||
"phpmd/phpmd": "^2.10"
|
||||
},
|
||||
"support": {
|
||||
"email": "support@retailcrm.ru"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "RetailCrm\\": "src/" }
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "0.1-dev"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"bin-dir": "vendor/bin",
|
||||
"process-timeout": 600
|
||||
},
|
||||
"scripts": {
|
||||
"phpunit": "./vendor/bin/phpunit -c phpunit.xml.dist --coverage-text",
|
||||
"phpunit-ci": "@php -dpcov.enabled=1 -dpcov.directory=. -dpcov.exclude=\"~vendor~\" ./vendor/bin/phpunit --teamcity -c phpunit.xml.dist",
|
||||
"phpmd": "./vendor/bin/phpmd src text ./phpmd.xml",
|
||||
"phpcs": "./vendor/bin/phpcs -p src --runtime-set testVersion 7.3-8.0 && ./vendor/bin/phpcs -p tests --runtime-set testVersion 7.3-8.0 --warning-severity=0",
|
||||
"phpstan": "./vendor/bin/phpstan analyse -c phpstan.neon src --memory-limit=-1",
|
||||
"verify": [
|
||||
"@phpcs",
|
||||
"@phpmd",
|
||||
"@phpstan",
|
||||
"@phpunit"
|
||||
]
|
||||
}
|
||||
}
|
13
phpcs.xml.dist
Normal file
13
phpcs.xml.dist
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="vendor/squizlabs/php_codesniffer/phpcs.xsd">
|
||||
<arg name="basepath" value="."/>
|
||||
<arg name="cache" value=".php_cs.cache"/>
|
||||
<arg name="colors"/>
|
||||
<arg name="extensions" value="php"/>
|
||||
|
||||
<rule ref="PSR12"/>
|
||||
|
||||
<file>src/</file>
|
||||
<file>tests/</file>
|
||||
</ruleset>
|
47
phpmd.xml
Normal file
47
phpmd.xml
Normal file
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ruleset name="Ruleset"
|
||||
xmlns="http://pmd.sf.net/ruleset/1.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
|
||||
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
|
||||
<description>Ruleset</description>
|
||||
<rule ref="rulesets/controversial.xml" />
|
||||
<rule ref="rulesets/unusedcode.xml" />
|
||||
|
||||
<rule ref="rulesets/design.xml">
|
||||
<exclude name="CouplingBetweenObjects" />
|
||||
</rule>
|
||||
<rule ref="rulesets/cleancode.xml">
|
||||
<exclude name="StaticAccess" />
|
||||
</rule>
|
||||
<rule ref="rulesets/codesize.xml">
|
||||
<exclude name="TooManyPublicMethods" />
|
||||
<exclude name="TooManyFields" />
|
||||
</rule>
|
||||
<rule ref="rulesets/naming.xml">
|
||||
<exclude name="ShortVariable" />
|
||||
</rule>
|
||||
|
||||
<rule ref="rulesets/naming.xml/ShortVariable">
|
||||
<properties>
|
||||
<property name="minimum" value="2" />
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="rulesets/codesize.xml/TooManyPublicMethods">
|
||||
<properties>
|
||||
<property name="maxmethods" value="20" />
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="rulesets/codesize.xml/TooManyFields">
|
||||
<properties>
|
||||
<property name="maxfields" value="30" />
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="rulesets/design.xml/CouplingBetweenObjects">
|
||||
<properties>
|
||||
<property name="maximum" value="15" />
|
||||
</properties>
|
||||
</rule>
|
||||
|
||||
<exclude-pattern>tests/*</exclude-pattern>
|
||||
</ruleset>
|
52
phpstan-baseline.neon
Normal file
52
phpstan-baseline.neon
Normal file
@ -0,0 +1,52 @@
|
||||
parameters:
|
||||
ignoreErrors:
|
||||
-
|
||||
message: "#^Access to an undefined property Symfony\\\\Component\\\\Validator\\\\Constraint\\:\\:\\$authFail\\.$#"
|
||||
count: 1
|
||||
path: src/Validator/CrmUrlValidator.php
|
||||
|
||||
-
|
||||
message: "#^Access to an undefined property Symfony\\\\Component\\\\Validator\\\\Constraint\\:\\:\\$domainFail\\.$#"
|
||||
count: 1
|
||||
path: src/Validator/CrmUrlValidator.php
|
||||
|
||||
-
|
||||
message: "#^Access to an undefined property Symfony\\\\Component\\\\Validator\\\\Constraint\\:\\:\\$fragmentFail\\.$#"
|
||||
count: 1
|
||||
path: src/Validator/CrmUrlValidator.php
|
||||
|
||||
-
|
||||
message: "#^Access to an undefined property Symfony\\\\Component\\\\Validator\\\\Constraint\\:\\:\\$getFileError\\.$#"
|
||||
count: 1
|
||||
path: src/Validator/CrmUrlValidator.php
|
||||
|
||||
-
|
||||
message: "#^Access to an undefined property Symfony\\\\Component\\\\Validator\\\\Constraint\\:\\:\\$noValidUrl\\.$#"
|
||||
count: 1
|
||||
path: src/Validator/CrmUrlValidator.php
|
||||
|
||||
-
|
||||
message: "#^Access to an undefined property Symfony\\\\Component\\\\Validator\\\\Constraint\\:\\:\\$noValidUrlHost\\.$#"
|
||||
count: 1
|
||||
path: src/Validator/CrmUrlValidator.php
|
||||
|
||||
-
|
||||
message: "#^Access to an undefined property Symfony\\\\Component\\\\Validator\\\\Constraint\\:\\:\\$pathFail\\.$#"
|
||||
count: 1
|
||||
path: src/Validator/CrmUrlValidator.php
|
||||
|
||||
-
|
||||
message: "#^Access to an undefined property Symfony\\\\Component\\\\Validator\\\\Constraint\\:\\:\\$portFail\\.$#"
|
||||
count: 1
|
||||
path: src/Validator/CrmUrlValidator.php
|
||||
|
||||
-
|
||||
message: "#^Access to an undefined property Symfony\\\\Component\\\\Validator\\\\Constraint\\:\\:\\$queryFail\\.$#"
|
||||
count: 1
|
||||
path: src/Validator/CrmUrlValidator.php
|
||||
|
||||
-
|
||||
message: "#^Access to an undefined property Symfony\\\\Component\\\\Validator\\\\Constraint\\:\\:\\$schemeFail\\.$#"
|
||||
count: 1
|
||||
path: src/Validator/CrmUrlValidator.php
|
||||
|
8
phpstan.neon
Normal file
8
phpstan.neon
Normal file
@ -0,0 +1,8 @@
|
||||
includes:
|
||||
- phpstan-baseline.neon
|
||||
|
||||
parameters:
|
||||
level: 5
|
||||
paths:
|
||||
- src
|
||||
- tests
|
36
phpunit.xml.dist
Normal file
36
phpunit.xml.dist
Normal file
@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- https://phpunit.de/manual/current/en/appendixes.configuration.html -->
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"
|
||||
backupGlobals="false"
|
||||
colors="false"
|
||||
bootstrap="tests/bootstrap.php"
|
||||
backupStaticAttributes="false"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="false"
|
||||
convertWarningsToExceptions="false"
|
||||
processIsolation="true"
|
||||
stopOnError="false"
|
||||
stopOnFailure="false"
|
||||
stopOnIncomplete="false"
|
||||
stopOnSkipped="false"
|
||||
stopOnRisky="false"
|
||||
>
|
||||
<coverage>
|
||||
<include>
|
||||
<directory>src</directory>
|
||||
<directory>dev</directory>
|
||||
</include>
|
||||
<report>
|
||||
<clover outputFile="coverage.xml"/>
|
||||
</report>
|
||||
</coverage>
|
||||
<testsuites>
|
||||
<testsuite name="Project Test Suite">
|
||||
<directory>tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<logging>
|
||||
<junit outputFile="test-report.xml"/>
|
||||
</logging>
|
||||
</phpunit>
|
70
src/Validator/CrmUrl.php
Normal file
70
src/Validator/CrmUrl.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace RetailCrm\Validator;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
|
||||
/**
|
||||
* Class CrmUrl
|
||||
*
|
||||
* @Annotation
|
||||
* @Target({"PROPERTY"})
|
||||
* @package Retailcrm\Validator
|
||||
*/
|
||||
class CrmUrl extends Constraint
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $schemeFail = 'Incorrect protocol. Only https is allowed.';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $pathFail = 'The domain path must be empty.';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $portFail = 'The port does not need to be specified.';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $domainFail = 'An invalid domain is specified.';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $noValidUrlHost = 'Incorrect Host URL.';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $noValidUrl = 'Incorrect URL.';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $queryFail = 'The query must be blank.';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $fragmentFail = 'The fragment should be blank.';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $authFail = 'No need to provide authorization data.';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $getFileError = 'Unable to obtain reference values.';
|
||||
|
||||
public function getTargets()
|
||||
{
|
||||
return self::PROPERTY_CONSTRAINT;
|
||||
}
|
||||
}
|
241
src/Validator/CrmUrlValidator.php
Normal file
241
src/Validator/CrmUrlValidator.php
Normal file
@ -0,0 +1,241 @@
|
||||
<?php
|
||||
|
||||
namespace RetailCrm\Validator;
|
||||
|
||||
use JsonException;
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ConstraintValidator;
|
||||
|
||||
/**
|
||||
* Class CrmUrlValidator
|
||||
*
|
||||
* @package Retailcrm\Validator
|
||||
*/
|
||||
class CrmUrlValidator extends ConstraintValidator
|
||||
{
|
||||
public const BOX_DOMAINS_URL = "https://infra-data.retailcrm.tech/box-domains.json";
|
||||
public const CRM_DOMAINS_URL = "https://infra-data.retailcrm.tech/crm-domains.json";
|
||||
|
||||
/**
|
||||
* @var \Symfony\Component\Validator\Constraint
|
||||
*/
|
||||
private $constraint;
|
||||
|
||||
/**
|
||||
* Validate CRM URL
|
||||
*
|
||||
* @param mixed $value URL from form
|
||||
* @param Constraint $constraint Restriction for validation
|
||||
*/
|
||||
public function validate($value, Constraint $constraint): void
|
||||
{
|
||||
$this->constraint = $constraint;
|
||||
$filteredUrl = filter_var($value, FILTER_VALIDATE_URL);
|
||||
|
||||
if (false === $filteredUrl) {
|
||||
$this->context->buildViolation($constraint->noValidUrl)->addViolation();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$urlArray = parse_url($filteredUrl);
|
||||
|
||||
if ($this->checkUrlFormat($urlArray)) {
|
||||
$mainDomain = $this->getMainDomain($urlArray['host']);
|
||||
$existInCrm = $this->checkDomains(self::CRM_DOMAINS_URL, $mainDomain);
|
||||
$existInBox = $this->checkDomains(self::BOX_DOMAINS_URL, $urlArray['host']);
|
||||
|
||||
if (false === $existInCrm && false === $existInBox) {
|
||||
$this->context->buildViolation($constraint->domainFail)->addViolation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $crmUrl
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function checkUrlFormat(array $crmUrl): bool
|
||||
{
|
||||
$checkResult = true;
|
||||
$checkAuth = $this->checkAuth($crmUrl);
|
||||
$checkFragment = $this->checkFragment($crmUrl);
|
||||
$checkHost = $this->checkHost($crmUrl);
|
||||
$checkPath = $this->checkPath($crmUrl);
|
||||
$checkPort = $this->checkPort($crmUrl);
|
||||
$checkQuery = $this->checkQuery($crmUrl);
|
||||
$checkScheme = $this->checkScheme($crmUrl);
|
||||
|
||||
if (
|
||||
!$checkAuth
|
||||
|| !$checkFragment
|
||||
|| !$checkHost
|
||||
|| !$checkPath
|
||||
|| !$checkPort
|
||||
|| !$checkQuery
|
||||
|| !$checkScheme
|
||||
) {
|
||||
$checkResult = false;
|
||||
}
|
||||
|
||||
return $checkResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $crmUrl
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function checkHost(array $crmUrl): bool
|
||||
{
|
||||
if (!isset($crmUrl['host'])) {
|
||||
$this->context->buildViolation($this->constraint->noValidUrlHost)->addViolation();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $crmUrl
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function checkQuery(array $crmUrl): bool
|
||||
{
|
||||
if (isset($crmUrl['query']) && !empty($crmUrl['query'])) {
|
||||
$this->context->buildViolation($this->constraint->queryFail)->addViolation();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $crmUrl
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function checkAuth(array $crmUrl): bool
|
||||
{
|
||||
if (
|
||||
(isset($crmUrl['pass']) && !empty($crmUrl['pass']))
|
||||
|| (isset($crmUrl['user']) && !empty($crmUrl['user']))
|
||||
) {
|
||||
$this->context->buildViolation($this->constraint->authFail)->addViolation();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $crmUrl
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function checkFragment(array $crmUrl): bool
|
||||
{
|
||||
if (isset($crmUrl['fragment']) && !empty($crmUrl['fragment'])) {
|
||||
$this->context->buildViolation($this->constraint->fragmentFail)->addViolation();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $crmUrl
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function checkScheme(array $crmUrl): bool
|
||||
{
|
||||
if (isset($crmUrl['scheme']) && $crmUrl['scheme'] !== 'https') {
|
||||
$this->context->buildViolation($this->constraint->schemeFail)->addViolation();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $crmUrl
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function checkPath(array $crmUrl): bool
|
||||
{
|
||||
if (isset($crmUrl['path']) && $crmUrl['path'] !== '/' && $crmUrl['path'] !== '') {
|
||||
$this->context->buildViolation($this->constraint->pathFail)->addViolation();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $crmUrl
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function checkPort(array $crmUrl): bool
|
||||
{
|
||||
if (isset($crmUrl['port']) && !empty($crmUrl['port'])) {
|
||||
$this->context->buildViolation($this->constraint->portFail)->addViolation();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $domainUrl
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getValidDomains(string $domainUrl): array
|
||||
{
|
||||
try {
|
||||
$content = json_decode(file_get_contents($domainUrl), true, 512, JSON_THROW_ON_ERROR);
|
||||
|
||||
return array_column($content['domains'], 'domain');
|
||||
} catch (JsonException $exception) {
|
||||
$this->context->buildViolation($this->constraint->getFileError)->addViolation();
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $host
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getMainDomain(string $host): string
|
||||
{
|
||||
$hostArray = explode('.', $host);
|
||||
unset($hostArray[0]);
|
||||
|
||||
return implode('.', $hostArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $crmDomainsUrl
|
||||
* @param string $domainHost
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function checkDomains(string $crmDomainsUrl, string $domainHost): bool
|
||||
{
|
||||
return in_array($domainHost, $this->getValidDomains($crmDomainsUrl), true);
|
||||
}
|
||||
}
|
20
tests/Validator/CrmUrlTest.php
Normal file
20
tests/Validator/CrmUrlTest.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace RetailCrm\Tests\Validator;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use RetailCrm\Validator\CrmUrl;
|
||||
|
||||
/**
|
||||
* Class CrmUrlTest
|
||||
*
|
||||
* @package RetailCrm\Tests\Validator
|
||||
*/
|
||||
class CrmUrlTest extends TestCase
|
||||
{
|
||||
public function testGetTargets(): void
|
||||
{
|
||||
$crmUrl = new CrmUrl();
|
||||
self::assertEquals('property', $crmUrl->getTargets());
|
||||
}
|
||||
}
|
138
tests/Validator/CrmUrlValidatorTest.php
Normal file
138
tests/Validator/CrmUrlValidatorTest.php
Normal file
@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
namespace RetailCrm\Tests\Validator;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use RetailCrm\Validator\CrmUrl;
|
||||
use RetailCrm\Validator\CrmUrlValidator;
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ConstraintValidatorFactory;
|
||||
use Symfony\Component\Validator\Context\ExecutionContext;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextFactory;
|
||||
use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory;
|
||||
use Symfony\Component\Validator\Validation;
|
||||
use Symfony\Component\Validator\Validator\RecursiveValidator;
|
||||
use Symfony\Contracts\Translation\LocaleAwareInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorTrait;
|
||||
|
||||
class CrmUrlValidatorTest extends TestCase
|
||||
{
|
||||
public function testValidateSuccess(): void
|
||||
{
|
||||
$validCrms = [
|
||||
'https://asd.retailcrm.ru',
|
||||
'https://test.retailcrm.pro',
|
||||
'https://raisa.retailcrm.es',
|
||||
'https://blabla.simla.com',
|
||||
'https://blabla.simlachat.com',
|
||||
'https://blabla.simlachat.ru',
|
||||
'https://blabla.ecomlogic.com',
|
||||
'https://retailcrm.inventive.ru',
|
||||
'https://crm.baucenter.ru',
|
||||
'https://crm.holodilnik.ru',
|
||||
'https://crm.eco.lanit.ru',
|
||||
'https://ecom.inventive.ru',
|
||||
'https://retailcrm.tvoydom.ru',
|
||||
];
|
||||
|
||||
$translator = new class () implements TranslatorInterface, LocaleAwareInterface {
|
||||
use TranslatorTrait;
|
||||
};
|
||||
|
||||
$metadata = new LazyLoadingMetadataFactory();
|
||||
$factory = new ExecutionContextFactory($translator);
|
||||
$validator = new CrmUrlValidator();
|
||||
|
||||
foreach ($validCrms as $validCrm) {
|
||||
$context = new ExecutionContext(
|
||||
new RecursiveValidator($factory, $metadata, new ConstraintValidatorFactory()),
|
||||
CrmUrl::class,
|
||||
$translator
|
||||
);
|
||||
|
||||
$context->setConstraint(new CrmUrl());
|
||||
$validator->initialize($context);
|
||||
$validator->validate($validCrm, new CrmUrl());
|
||||
|
||||
self::assertEmpty($context->getViolations());
|
||||
}
|
||||
}
|
||||
|
||||
public function testValidateFailed(): void
|
||||
{
|
||||
$failedUrls = [
|
||||
[
|
||||
'url' => 'http://asd.retailcrm.ru',
|
||||
'errors' => ['Incorrect protocol. Only https is allowed.'],
|
||||
],
|
||||
[
|
||||
'url' => 'https://test.retailcrm.pro:8080',
|
||||
'errors' => ['The port does not need to be specified.'],
|
||||
],
|
||||
[
|
||||
'url' => 'https://raisa.retailcrm.ess',
|
||||
'errors' => ['An invalid domain is specified.'],
|
||||
],
|
||||
[
|
||||
'url' => 'https://blabla.simlla.com',
|
||||
'errors' => ['An invalid domain is specified.'],
|
||||
],
|
||||
[
|
||||
'url' => 'https:/blabla.simlachat.ru',
|
||||
'errors' => [
|
||||
'Incorrect URL.',
|
||||
],
|
||||
],
|
||||
[
|
||||
'url' => 'htttps://blabla.ecomlogic.com',
|
||||
'errors' => ['Incorrect protocol. Only https is allowed.'],
|
||||
],
|
||||
[
|
||||
'url' => 'https://blabla.ecomlogic.com/test',
|
||||
'errors' => ['The domain path must be empty.'],
|
||||
],
|
||||
[
|
||||
'url' => 'htttps://blabla.eecomlogic.com/test',
|
||||
'errors' => [
|
||||
'The domain path must be empty.',
|
||||
'Incorrect protocol. Only https is allowed.',
|
||||
],
|
||||
],
|
||||
[
|
||||
'url' => 'https://test:test@blabla.eecomlogic.com/test?test=test#fragment',
|
||||
'errors' => [
|
||||
'No need to provide authorization data.',
|
||||
'The fragment should be blank.',
|
||||
'The domain path must be empty.',
|
||||
'The query must be blank.',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$translator = new class () implements TranslatorInterface, LocaleAwareInterface {
|
||||
use TranslatorTrait;
|
||||
};
|
||||
|
||||
$metadata = new LazyLoadingMetadataFactory();
|
||||
$factory = new ExecutionContextFactory($translator);
|
||||
$validator = new CrmUrlValidator();
|
||||
|
||||
foreach ($failedUrls as $failedUrl) {
|
||||
$context = new ExecutionContext(
|
||||
new RecursiveValidator($factory, $metadata, new ConstraintValidatorFactory()),
|
||||
CrmUrl::class,
|
||||
$translator
|
||||
);
|
||||
$context->setConstraint(new CrmUrl());
|
||||
$validator->initialize($context);
|
||||
$validator->validate($failedUrl['url'], new CrmUrl());
|
||||
|
||||
foreach ($failedUrl['errors'] as $key => $error) {
|
||||
self::assertEquals($context->getViolations()->get($key)->getMessage(), $failedUrl['errors'][$key]);
|
||||
}
|
||||
|
||||
self::assertCount($context->getViolations()->count(), $failedUrl['errors']);
|
||||
}
|
||||
}
|
||||
}
|
1
tests/bootstrap.php
Normal file
1
tests/bootstrap.php
Normal file
@ -0,0 +1 @@
|
||||
<?php
|
Loading…
Reference in New Issue
Block a user