Skip to content

Commit de7a747

Browse files
committed
feat(domain): add UserProfile domain model with value objects, enums and tests
- Introduced new domain entities: - `UserProfile` aggregate with immutability and rich behaviors - Value Objects: `Email`, `UserId` - Supporting attribute: `Length` - Enums: `UserRole`, `UserStatus` - Added full test coverage: - Unit tests for enums, value objects, and UserProfile - Integration test covering full user lifecycle flow - Updated configuration and tooling: - Adjusted `.gitignore` and `Makefile` - Updated `composer.json` dependencies and autoload - Refined `phpunit.xml` for PHPUnit 12 compatibility
1 parent d54c84b commit de7a747

14 files changed

Lines changed: 1073 additions & 17 deletions

.gitignore

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -124,20 +124,6 @@ $RECYCLE.BIN/
124124
# Created by php-api-stack image for demo/testing
125125
/public/
126126

127-
# ============================================================================
128-
# COMPONENT DEVELOPMENT
129-
# ============================================================================
130-
# When developing specific components, these are component-specific
131-
# DevKit base doesn't have src/tests, but components created will
132-
/src/
133-
/tests/Unit/
134-
/tests/Integration/
135-
/tests/Fixtures/
136-
137-
# Keep base test structure
138-
!/tests/
139-
!/tests/.gitkeep
140-
141127
# ============================================================================
142128
# DOCUMENTATION BUILD
143129
# ============================================================================

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ outdated: ## Show outdated packages
107107

108108
test: ## Run all tests
109109
@echo "$(BLUE)🧪 Running tests...$(NC)"
110-
@$(EXEC_PHP) vendor/bin/phpunit
110+
@$(EXEC_PHP) vendor/bin/phpunit --no-coverage --testdox
111111
@echo "$(GREEN)✓ Tests completed$(NC)"
112112

113113
test-coverage: ## Run tests with coverage report (HTML)

composer.json

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,26 @@
2424
"source": "https://github.com/KaririCode-Framework/kariricode-devkit",
2525
"docs": "https://kariricode.org/docs/devkit"
2626
},
27+
"autoload": {
28+
"psr-4": {
29+
"KaririCode\\DevKit\\": "src/"
30+
}
31+
},
32+
"autoload-dev": {
33+
"psr-4": {
34+
"KaririCode\\DevKit\\Tests\\": "tests/"
35+
}
36+
},
2737
"require": {
2838
"php": "^8.3"
2939
},
3040
"require-dev": {
3141
"phpunit/phpunit": "12.4.1",
32-
"friendsofphp/php-cs-fixer": "^3.64",
42+
"friendsofphp/php-cs-fixer": "3.89.0",
3343
"phpstan/phpstan": "^2.0",
3444
"phpstan/phpstan-strict-rules": "^2.0",
3545
"phpmd/phpmd": "^2.15",
36-
"rector/rector": "2.2.3"
46+
"rector/rector": "2.2.4"
3747
},
3848
"scripts": {
3949
"post-install-cmd": [

phpunit.xml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/12.4/phpunit.xsd"
5+
bootstrap="vendor/autoload.php"
6+
cacheDirectory=".phpunit.cache"
7+
colors="true"
8+
executionOrder="random"
9+
beStrictAboutTestsThatDoNotTestAnything="true"
10+
beStrictAboutOutputDuringTests="true"
11+
failOnWarning="true"
12+
failOnRisky="true"
13+
failOnIncomplete="true"
14+
failOnSkipped="false"
15+
>
16+
17+
<testsuites>
18+
<testsuite name="Unit Tests">
19+
<directory suffix="Test.php">tests/Unit</directory>
20+
</testsuite>
21+
<testsuite name="Integration Tests">
22+
<directory suffix="Test.php">tests/Integration</directory>
23+
</testsuite>
24+
</testsuites>
25+
26+
<!-- Code Coverage (ativa se houver driver disponível) -->
27+
<coverage>
28+
<include>
29+
<directory suffix=".php">src</directory>
30+
</include>
31+
<exclude>
32+
<directory>vendor</directory>
33+
<directory>devkit</directory>
34+
<directory>tests</directory>
35+
</exclude>
36+
<report>
37+
<clover outputFile="build/coverage/clover.xml"/>
38+
<html outputDirectory="build/coverage/html"/>
39+
<text outputFile="php://stdout" showUncoveredFiles="false"/>
40+
</report>
41+
</coverage>
42+
43+
<logging>
44+
<junit outputFile="build/junit.xml"/>
45+
<testdoxText outputFile="build/testdox.txt"/>
46+
</logging>
47+
48+
<php>
49+
<env name="APP_ENV" value="testing"/>
50+
<env name="XDEBUG_MODE" value="coverage"/>
51+
<ini name="zend.assertions" value="1"/>
52+
<ini name="assert.exception" value="1"/>
53+
<ini name="memory_limit" value="512M"/>
54+
</php>
55+
56+
</phpunit>

src/Email.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KaririCode\DevKit;
6+
7+
use InvalidArgumentException;
8+
use JsonSerializable;
9+
use Stringable;
10+
11+
/**
12+
* Email — Value Object for a user's email address.
13+
*
14+
* Ensures that email addresses are always valid.
15+
*
16+
* @package KaririCode\DevKit
17+
* @category Query Filtering
18+
* @author Walmir Silva <walmir.silva@kariricode.org>
19+
* @copyright 2025 KaririCode
20+
* @license MIT
21+
* @version 1.0.0
22+
* @since 1.0.0
23+
*/
24+
final readonly class Email implements Stringable, JsonSerializable
25+
{
26+
public function __construct(
27+
#[Length(min: 3, max: 320)]
28+
public string $value,
29+
) {
30+
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
31+
throw new InvalidArgumentException("Invalid email: {$value}");
32+
}
33+
}
34+
35+
public function __toString(): string
36+
{
37+
return $this->value;
38+
}
39+
40+
public function jsonSerialize(): string
41+
{
42+
return $this->value;
43+
}
44+
}

src/Length.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KaririCode\DevKit;
6+
7+
use Attribute;
8+
9+
/**
10+
* Length — Attribute for property length validation.
11+
*
12+
* Defines minimum and maximum length constraints for string properties.
13+
*
14+
* @package KaririCode\DevKit
15+
* @category Validation
16+
* @author Walmir Silva <walmir.silva@kariricode.org>
17+
* @copyright 2025 KaririCode
18+
* @license MIT
19+
* @version 1.0.0
20+
* @since 1.0.0
21+
*/
22+
#[Attribute(Attribute::TARGET_PROPERTY)]
23+
class Length
24+
{
25+
public function __construct(
26+
public readonly int $min = 0,
27+
public readonly int $max = PHP_INT_MAX,
28+
) {}
29+
}

src/UserId.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KaririCode\DevKit;
6+
7+
use InvalidArgumentException;
8+
use JsonSerializable;
9+
use Stringable;
10+
11+
/**
12+
* UserId — Value Object for a user's unique identifier.
13+
*
14+
* Ensures that user IDs are always non-empty strings.
15+
*
16+
* @package KaririCode\DevKit
17+
* @category Query Filtering
18+
* @author Walmir Silva <walmir.silva@kariricode.org>
19+
* @copyright 2025 KaririCode
20+
* @license MIT
21+
* @version 1.0.0
22+
* @since 1.0.0
23+
*/
24+
final readonly class UserId implements Stringable, JsonSerializable
25+
{
26+
public function __construct(
27+
#[Length(min: 1, max: 50)]
28+
public string $value,
29+
) {
30+
if (empty($value)) {
31+
throw new InvalidArgumentException("User ID cannot be empty.");
32+
}
33+
}
34+
35+
public function __toString(): string
36+
{
37+
return $this->value;
38+
}
39+
40+
public function jsonSerialize(): string
41+
{
42+
return $this->value;
43+
}
44+
}

0 commit comments

Comments
 (0)