Skip to content

Commit

Permalink
Finalizado desenvolvimento do projeto
Browse files Browse the repository at this point in the history
  • Loading branch information
Jhon-Henkel committed Feb 5, 2023
1 parent fad4f05 commit ef6f304
Show file tree
Hide file tree
Showing 13 changed files with 361 additions and 21 deletions.
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,6 @@ Para iniciar asse projeto, basta executar os seguintes passos:
- ***verify***: é do tipo **boolean** retornando se a determinada string violou ou não nas regras.
- ***noMatch***: é do tipo **array** retornando as regras que essa string violou, caso não tenha violado nenhuma, será retornado um **array** vazio.
---
## *Lógica utilizada*
- **Sistema de rotas**: utilizei a reescrita do apache para fazer as rotas e garantir que somente a rota verify seria utilizada e somente seria enviado post para essa rota.
- **Validação de parâmetros post**: fiz um validador para validar se a regra enviada é válida, se os atributos obrigatórios estão sendo enviados e se o tipo de cada atributo está correto.
---
## *Como rodar os testes*
- ***Unitários***: composer run php-unit
- ***Coverage***: composer run php-coverage - Após rodar irá ficar em **tests/coverage**
Expand Down
2 changes: 1 addition & 1 deletion RouteSwitch.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use src\Tools\RequestTools;
use src\Controller\PasswordVerifyController;
use src\Api\Response;
use src\API\Response;

abstract class RouteSwitch
{
Expand Down
3 changes: 2 additions & 1 deletion phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
<directory suffix=".php">src</directory>
</include>
<exclude>
<directory>src/Api</directory>
<directory>src/API</directory>
<directory>src/Controller</directory>
<directory>src/Enums</directory>
<directory>src/Exceptions</directory>
</exclude>
Expand Down
4 changes: 2 additions & 2 deletions src/Api/Response.php → src/API/Response.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace src\Api;
namespace src\API;

use src\Enums\HttpStatusCode;

Expand Down Expand Up @@ -32,7 +32,7 @@ public static function renderBadRequest(?string $message): void
{
self::render(
HttpStatusCode::BAD_REQUEST,
'Bad Request! ' . $message
$message
);
}

Expand Down
27 changes: 27 additions & 0 deletions src/BO/PasswordVerifyBO.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,31 @@ protected function validateRulesPost(array $rules): bool
}
return true;
}

public function verify(stdClass $object): array
{
$ruleBO = new RuleBO();
$rulesVerified = array();
foreach ($object->rules as $rule) {
$ruleName = $rule->rule;
$rulesVerified[$rule->rule] = $ruleBO->$ruleName($object->password, $rule->value);
}
return $rulesVerified;
}

public function populateReturn(array $rulesResults): array
{
$return = array('verify' => true, 'noMatch' => array());
$rulesBroken = array();
foreach ($rulesResults as $rule => $result) {
if (!$result) {
$return['verify'] = false;
$rulesBroken[] = $rule;
}
}
if (!$return['verify']) {
$return['noMatch'][] = implode(', ', $rulesBroken);
}
return $return;
}
}
53 changes: 53 additions & 0 deletions src/BO/RuleBO.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace src\BO;

class RuleBO
{
public function minSize(string $password, int $value): bool
{
return strlen($password) >= $value;
}

public function minUppercase(string $password, int $value): bool
{
$upperChars = preg_match_all("/[A-Z]/", $password);
return $upperChars >= $value;
}

public function minLowercase(string $password, int $value): bool
{
$lowerChars = preg_match_all("/[a-z]/", $password);
return $lowerChars >= $value;
}

public function minDigit(string $password, int $value): bool
{
$digitChars = preg_match_all("/[0-9]/", $password);
return $digitChars >= $value;
}

public function minSpecialChars(string $password, int $value): bool
{
$specialChars = '"%!%¨¬@$\'-+_*;<>?^§ªº~£¢¹²³^:.,´`{|}~/\\#=&[]()';
$pattern = preg_quote($specialChars, '/');
$digitChars = preg_match_all('/[' . $pattern . ']/', $password);
return $digitChars >= $value;
}

public function noRepeated(string $password): bool
{
$arrayChars = str_split($password);
for ($index = 0; $index < count($arrayChars); $index ++) {
if ($index == count($arrayChars) - 1) {
break;
}
$atualChar = $arrayChars[$index];
$nextChar = $arrayChars[$index + 1];
if ($atualChar == $nextChar) {
return false;
}
}
return true;
}
}
16 changes: 12 additions & 4 deletions src/Controller/PasswordVerifyController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

namespace src\Controller;

use src\Api\Response;
use src\API\Response;
use src\BO\PasswordVerifyBO;
use src\Enums\HttpStatusCode;
use src\Exceptions\AttributeMissingException;
use src\Exceptions\InvalidRuleException;
use src\Exceptions\InvalidTypeException;
use stdClass;

Expand All @@ -21,9 +23,15 @@ public function verifyPassword(stdClass $object)
{
try {
$this->bo->validatePostObject($object);
d($object);
die();
} catch (InvalidTypeException|AttributeMissingException $exception) {
$verify = $this->bo->verify($object);
$return = $this->bo->populateReturn($verify);
Response::render(HttpStatusCode::OK, $return);
} catch (
InvalidTypeException
|AttributeMissingException
|InvalidRuleException
$exception
) {
Response::renderBadRequest($exception->getMessage());
}
}
Expand Down
1 change: 1 addition & 0 deletions src/Enums/HttpStatusCode.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

class HttpStatusCode
{
const OK = 200;
const BAD_REQUEST = 400;
const NOT_FOUND = 404;
const METHOD_NOT_ALLOWED = 405;
Expand Down
5 changes: 4 additions & 1 deletion src/Tools/MessagesTools.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace src\Tools;

use src\Enums\RulesEnum;

class MessagesTools
{
public static function invalidAttributeType(string $attribute, string $type): string
Expand All @@ -21,6 +23,7 @@ public static function attributeMissing(string $attribute): string

public static function invalidRule(string $rule): string
{
return 'Regra inválida: ' . $rule . ', consulte a documentação!';
$rules = implode(', ', RulesEnum::getRulesArray());
return 'Regra inválida: ' . $rule . ', as regras válidas são: ' . $rules;
}
}
95 changes: 88 additions & 7 deletions tests/Unit/BO/PasswordVerifyBoUnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,24 @@ class PasswordVerifyBoUnitTest extends TestCase
{
private stdClass $object;
private $passwordVerifyBoMock;
private array $rulesResults;

protected function setUp(): void
{
$this->object = $this->makeTestObject();
$this->passwordVerifyBoMock = $this->mockPasswordVerifyBo();
$this->rulesResults = $this->makeRuleResults();
}

private function makeTestObject(): stdClass
{
$rule = new stdClass();
$rule->rule = RulesEnum::NO_REPEATED;
$rule->value = 2;

$object = new stdClass();
$object->password = 'test123';
$object->rules = array($rule);

$object->rules = array(
json_decode('{"rule": "minSize", "value": 2}'),
json_decode('{"rule": "minUppercase", "value": 1}'),
json_decode('{"rule": "minDigit", "value": 3}')
);
return $object;
}

Expand All @@ -42,6 +43,15 @@ private function mockPasswordVerifyBo()
return $passwordVerifyBoMock;
}

private function makeRuleResults(): array
{
return array(
'minSize' => true,
'minUppercase' => true,
'minDigit' => true
);
}

protected function tearDown(): void
{
Mockery::close();
Expand Down Expand Up @@ -151,9 +161,11 @@ public function testValidateRulesPostWithInvalidValueType()
public function testValidateRulesPostWithInvalidRule()
{
$this->object->rules[0]->rule = 'aaa';
$expectMessage = 'Regra inválida: aaa, as regras válidas são: minDigit, ';
$expectMessage .= 'minLowercase, minSize, minSpecialChars, minUppercase, noRepeated';

$this->expectExceptionMessage(InvalidRuleException::class);
$this->expectExceptionMessage('Regra inválida: aaa, consulte a documentação!');
$this->expectExceptionMessage($expectMessage);

$this->passwordVerifyBoMock->validateRulesPost($this->object->rules);
}
Expand All @@ -162,4 +174,73 @@ public function testValidateRulesPostWithValidRule()
{
$this->assertTrue($this->passwordVerifyBoMock->validateRulesPost($this->object->rules));
}

public function testVerifyWithRulesReturnTrue()
{
$this->object->password = 'Teste123';
$verify = $this->passwordVerifyBoMock->verify($this->object);

$this->assertIsArray($verify);
$this->assertCount(3, $verify);
$this->assertTrue($verify[RulesEnum::MIN_SIZE]);
$this->assertTrue($verify[RulesEnum::MIN_UPPERCASE]);
$this->assertTrue($verify[RulesEnum::MIN_DIGIT]);
}

public function testVerifyWithOneRuleBroken()
{
$this->object->password = 'Teste';
$verify = $this->passwordVerifyBoMock->verify($this->object);

$this->assertIsArray($verify);
$this->assertCount(3, $verify);
$this->assertTrue($verify[RulesEnum::MIN_SIZE]);
$this->assertTrue($verify[RulesEnum::MIN_UPPERCASE]);
$this->assertFalse($verify[RulesEnum::MIN_DIGIT]);
}

public function testVerifyWithThreeRulesBroken()
{
$this->object->password = 'q';
$verify = $this->passwordVerifyBoMock->verify($this->object);

$this->assertIsArray($verify);
$this->assertCount(3, $verify);
$this->assertFalse($verify[RulesEnum::MIN_SIZE]);
$this->assertFalse($verify[RulesEnum::MIN_UPPERCASE]);
$this->assertFalse($verify[RulesEnum::MIN_DIGIT]);
}

public function testPopulateReturnWithOneRuleBroken()
{
$this->rulesResults[RulesEnum::MIN_UPPERCASE] = false;
$return = $this->passwordVerifyBoMock->populateReturn($this->rulesResults);

$this->assertIsArray($return);
$this->assertCount(2, $return);
$this->assertFalse($return['verify']);
$this->assertEquals(array(RulesEnum::MIN_UPPERCASE), $return['noMatch']);
}

public function testPopulateReturnWithThreeRulesBroken()
{
$this->rulesResults[RulesEnum::MIN_UPPERCASE] = false;
$this->rulesResults[RulesEnum::MIN_DIGIT] = false;
$return = $this->passwordVerifyBoMock->populateReturn($this->rulesResults);

$this->assertIsArray($return);
$this->assertCount(2, $return);
$this->assertFalse($return['verify']);
$this->assertEquals(array("minUppercase, minDigit"), $return['noMatch']);
}

public function testPopulateReturnWithNoRulesBroken()
{
$return = $this->passwordVerifyBoMock->populateReturn($this->rulesResults);

$this->assertIsArray($return);
$this->assertCount(2, $return);
$this->assertTrue($return['verify']);
$this->assertEquals(array(), $return['noMatch']);
}
}
Loading

0 comments on commit ef6f304

Please sign in to comment.