Skip to content

Commit

Permalink
feat: adds new NotificationService
Browse files Browse the repository at this point in the history
  • Loading branch information
kajetan-nobel committed Sep 26, 2023
1 parent 88370a4 commit 4d650f1
Show file tree
Hide file tree
Showing 9 changed files with 155 additions and 37 deletions.
4 changes: 3 additions & 1 deletion src/DTO/BaseDto.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ private function castAttributes(array $attributes): array
public function castAttribute(string $castType, mixed $value): mixed
{
if (is_a($castType, BaseDto::class, true)) {
return new $castType($value ?? []);
return $value instanceof BaseDto
? $value
: new $castType($value ?? []);
}

if (enum_exists($castType)) {
Expand Down
9 changes: 9 additions & 0 deletions src/DTO/Notifications/OneClickNotificationDto.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,27 @@

namespace Routegroup\Imoje\Payment\DTO\Notifications;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Routegroup\Imoje\Payment\DTO\BaseDto;
use Routegroup\Imoje\Payment\DTO\Casts\PaymentDto;
use Routegroup\Imoje\Payment\DTO\Casts\TransactionDto;
use Routegroup\Imoje\Payment\Factories\Notifications\OneClickNotificationDtoFactory;

/**
* @property-read TransactionDto $transaction
* @property-read PaymentDto $payment
*/
class OneClickNotificationDto extends BaseDto
{
use HasFactory;

protected array $casts = [
'transaction' => TransactionDto::class,
'payment' => PaymentDto::class,
];

protected static function newFactory(): OneClickNotificationDtoFactory
{
return OneClickNotificationDtoFactory::new();
}
}
16 changes: 4 additions & 12 deletions src/Factories/Casts/PaymentDtoFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@
use Routegroup\Imoje\Payment\DTO\Casts\PaymentDto;
use Routegroup\Imoje\Payment\Factories\Factory;
use Routegroup\Imoje\Payment\Types\Currency;
use Routegroup\Imoje\Payment\Types\PaymentMethod;
use Routegroup\Imoje\Payment\Types\PaymentMethodCode;
use Routegroup\Imoje\Payment\Types\TransactionSource;
use Routegroup\Imoje\Payment\Types\TransactionStatus;
use Routegroup\Imoje\Payment\Types\TransactionType;

class PaymentDtoFactory extends Factory
{
Expand All @@ -23,17 +19,13 @@ public function definition(): array

return [
'id' => $this->faker->unique()->uuid,
'type' => TransactionType::REFUND->value,
'status' => TransactionStatus::SETTLED->value,
'source' => TransactionSource::API->value,
'amount' => $this->faker->numberBetween(1, 1000) * 100,
'status' => TransactionStatus::SETTLED,
'created' => $now->timestamp,
'orderId' => $this->faker->unique()->uuid,
'currency' => Currency::PLN,
'modified' => $now->timestamp,
'serviceId' => config('services.imoje.service_key'),
'amount' => $this->faker->numberBetween(1, 100) * 100,
'currency' => Currency::PLN->value,
'orderId' => $this->faker->unique()->uuid,
'paymentMethod' => PaymentMethod::CARD->value,
'paymentMethodCode' => PaymentMethodCode::ONECLICK->value,
];
}
}
30 changes: 12 additions & 18 deletions src/Factories/Casts/PaymentProfileDtoFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,30 @@

namespace Routegroup\Imoje\Payment\Factories\Casts;

use Illuminate\Support\Str;
use Routegroup\Imoje\Payment\DTO\Casts\PaymentProfileDto;
use Routegroup\Imoje\Payment\Factories\Factory;
use Routegroup\Imoje\Payment\Types\Currency;
use Routegroup\Imoje\Payment\Types\PaymentMethod;
use Routegroup\Imoje\Payment\Types\PaymentMethodCode;
use Routegroup\Imoje\Payment\Types\TransactionSource;
use Routegroup\Imoje\Payment\Types\TransactionStatus;
use Routegroup\Imoje\Payment\Types\TransactionType;

class PaymentProfileDtoFactory extends Factory
{
protected $model = PaymentProfileDto::class;

public function definition(): array
{
$now = now();
$expirationDate = $this->faker->creditCardExpirationDate;

return [
'id' => $this->faker->unique()->uuid,
'type' => TransactionType::REFUND->value,
'status' => TransactionStatus::SETTLED->value,
'source' => TransactionSource::API->value,
'created' => $now->timestamp,
'modified' => $now->timestamp,
'serviceId' => config('services.imoje.service_key'),
'amount' => $this->faker->numberBetween(1, 100) * 100,
'currency' => Currency::PLN->value,
'orderId' => $this->faker->unique()->uuid,
'paymentMethod' => PaymentMethod::CARD->value,
'paymentMethodCode' => PaymentMethodCode::ONECLICK->value,
'merchantMid' => Str::random(),
'merchantCustomerId' => $this->faker->unique()->numberBetween(1, 999999),
'firstName' => $this->faker->firstName,
'lastName' => $this->faker->lastName,
'maskedNumber' => $this->faker->numerify('****####'),
'month' => $expirationDate->format('m'),
'year' => $expirationDate->format('Y'),
'organization' => $this->faker->creditCardType,
'isActive' => 1,
'profile' => '',
];
}
}
23 changes: 17 additions & 6 deletions src/Factories/Casts/TransactionDtoFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,28 @@ public function definition(): array

return [
'id' => $this->faker->unique()->uuid,
'type' => TransactionType::REFUND->value,
'status' => TransactionStatus::SETTLED->value,
'source' => TransactionSource::API->value,
'type' => TransactionType::REFUND,
'status' => TransactionStatus::SETTLED,
'source' => TransactionSource::API,
'created' => $now->timestamp,
'modified' => $now->timestamp,
'serviceId' => config('services.imoje.service_key'),
'amount' => $this->faker->numberBetween(1, 100) * 100,
'currency' => Currency::PLN->value,
'currency' => Currency::PLN,
'orderId' => $this->faker->unique()->uuid,
'paymentMethod' => PaymentMethod::CARD->value,
'paymentMethodCode' => PaymentMethodCode::ONECLICK->value,
'paymentMethod' => $this->faker->randomElement(PaymentMethod::cases()),
'paymentMethodCode' => $this->faker->randomElement(PaymentMethodCode::cases()),
];
}

public function asOneClick(): static
{
return $this->state([
'type' => TransactionType::SALE,
'status' => TransactionStatus::SETTLED,
'source' => TransactionSource::WEB,
'paymentMethod' => PaymentMethod::CARD,
'paymentMethodCode' => PaymentMethodCode::ONECLICK,
]);
}
}
4 changes: 4 additions & 0 deletions src/Factories/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ abstract class Factory extends BaseFactory
{
public function create($attributes = [], Model $parent = null)
{
if (! empty($attributes)) {
return $this->state($attributes)->create([], $parent);
}

return $this->make($attributes, $parent);
}

Expand Down
23 changes: 23 additions & 0 deletions src/Factories/Notifications/OneClickNotificationDtoFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace Routegroup\Imoje\Payment\Factories\Notifications;

use Routegroup\Imoje\Payment\DTO\Casts\PaymentDto;
use Routegroup\Imoje\Payment\DTO\Casts\TransactionDto;
use Routegroup\Imoje\Payment\DTO\Notifications\OneClickNotificationDto;
use Routegroup\Imoje\Payment\Factories\Factory;

class OneClickNotificationDtoFactory extends Factory
{
protected $model = OneClickNotificationDto::class;

public function definition(): array
{
return [
'transaction' => TransactionDto::factory()->asOneClick(),
'payment' => PaymentDto::factory(),
];
}
}
62 changes: 62 additions & 0 deletions src/Services/NotificationService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

declare(strict_types=1);

namespace Routegroup\Imoje\Payment\Services;

use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Routegroup\Imoje\Payment\DTO\BaseDto;
use Routegroup\Imoje\Payment\DTO\Notifications\OneClickNotificationDto;
use Routegroup\Imoje\Payment\Exceptions\NotImplementedException;
use Routegroup\Imoje\Payment\Exceptions\SchemaValidationException;
use Routegroup\Imoje\Payment\Lib\Validator;
use Routegroup\Imoje\Payment\Types\PaymentMethod;
use Routegroup\Imoje\Payment\Types\PaymentMethodCode;
use Routegroup\Imoje\Payment\Types\TransactionSource;
use Routegroup\Imoje\Payment\Types\TransactionType;

class NotificationService
{
public function __construct(
public readonly Validator $validator
) {
}

/**
* @throws SchemaValidationException
* @throws NotImplementedException
*/
public function resolve(Request $request): BaseDto
{
$data = $request->toArray();

$this->validator->fromNotification($data);

if ($this->isOneClick($data)) {
return new OneClickNotificationDto($data);
}

throw new NotImplementedException($data);
}

protected function isOneClick(array $data): bool
{
return $this->isEqualWithStructure($data, [
'transaction' => [
'type' => TransactionType::SALE->value,
'source' => TransactionSource::WEB->value,
'paymentMethod' => PaymentMethod::CARD->value,
'paymentMethodCode' => PaymentMethodCode::ONECLICK->value,
],
]);
}

protected function isEqualWithStructure(array $data, array $structure): bool
{
$structure = Arr::dot($structure);
$data = Arr::dot($data);

return count($structure) === count(array_intersect($structure, $data));
}
}
21 changes: 21 additions & 0 deletions tests/Services/NotificationServiceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

use Illuminate\Http\Request;
use Routegroup\Imoje\Payment\DTO\BaseDto;
use Routegroup\Imoje\Payment\DTO\Notifications\OneClickNotificationDto;
use Routegroup\Imoje\Payment\Services\NotificationService;

beforeEach(function (): void {
$this->service = app(NotificationService::class);
});

function mockRequest(BaseDto $dto): Request
{
return new Request($dto->toArray());
}

it('returns OneClickNotification', function (): void {
$request = mockRequest(OneClickNotificationDto::factory()->make());
$result = $this->service->resolve($request);
expect($result)->toBeInstanceOf(OneClickNotificationDto::class);
});

0 comments on commit 4d650f1

Please sign in to comment.