add node to scheduled node

This commit is contained in:
Yisroel Baum 2026-04-27 09:28:43 +03:00
parent d47a0235d2
commit a9265abeae
Signed by: yisroelbaum
GPG key ID: 0FA60884F75520A9
8 changed files with 88 additions and 6 deletions

View file

@ -64,6 +64,7 @@ class CreatePlan
new CreateScheduledNodeRequest( new CreateScheduledNodeRequest(
date: $scheduledDate->format('Y-m-d'), date: $scheduledDate->format('Y-m-d'),
planId: $plan->getId(), planId: $plan->getId(),
nodeId: $node->getId(),
) )
); );
} }

View file

@ -20,6 +20,7 @@ class JsonScheduledNodeRepository implements ScheduledNodeRepository
'id' => $id, 'id' => $id,
'date' => $dto->date->format('Y-m-d'), 'date' => $dto->date->format('Y-m-d'),
'planId' => $dto->plan->getId(), 'planId' => $dto->plan->getId(),
'nodeId' => $dto->node->getId(),
]; ];
$this->writeScheduledNodes($scheduledNodes); $this->writeScheduledNodes($scheduledNodes);
@ -27,6 +28,7 @@ class JsonScheduledNodeRepository implements ScheduledNodeRepository
id: $id, id: $id,
date: $dto->date, date: $dto->date,
plan: $dto->plan, plan: $dto->plan,
node: $dto->node,
); );
} }

View file

@ -3,6 +3,7 @@
namespace App\ScheduledNode\UseCases; namespace App\ScheduledNode\UseCases;
use App\Exceptions\BadRequestException; use App\Exceptions\BadRequestException;
use App\Node\NodeRepository;
use App\Plan\PlanRepository; use App\Plan\PlanRepository;
use App\ScheduledNode\ScheduledNode; use App\ScheduledNode\ScheduledNode;
use App\ScheduledNode\CreateScheduledNodeDto; use App\ScheduledNode\CreateScheduledNodeDto;
@ -15,6 +16,7 @@ class CreateScheduledNode
public function __construct( public function __construct(
private ScheduledNodeRepository $scheduledNodeRepo, private ScheduledNodeRepository $scheduledNodeRepo,
private PlanRepository $planRepo, private PlanRepository $planRepo,
private NodeRepository $nodeRepo,
) {} ) {}
/** /**
@ -24,24 +26,40 @@ class CreateScheduledNode
public function execute( public function execute(
CreateScheduledNodeRequest $request CreateScheduledNodeRequest $request
): ScheduledNode { ): ScheduledNode {
if ($request->date === null) { $nodeId = $request->nodeId;
$planId = $request->planId;
$date = $request->date;
if ($date === null) {
throw new BadRequestException('date is required'); throw new BadRequestException('date is required');
} }
if ($request->planId === null) { if ($planId === null) {
throw new BadRequestException('planId is required'); throw new BadRequestException('planId is required');
} }
$id = $request->planId; if ($nodeId === null) {
$plan = $this->planRepo->find($id); throw new BadRequestException('nodeId is required');
}
$plan = $this->planRepo->find($planId);
if ($plan === null) { if ($plan === null) {
throw new DomainException("Plan with id: $id doesnt exist"); throw new DomainException(
"Plan with id: $planId doesnt exist"
);
}
$node = $this->nodeRepo->find($nodeId);
if ($node === null) {
throw new DomainException(
"Node with id: $nodeId doesnt exist"
);
} }
return $this->scheduledNodeRepo->create( return $this->scheduledNodeRepo->create(
new CreateScheduledNodeDto( new CreateScheduledNodeDto(
date: new DateTimeImmutable($request->date), date: new DateTimeImmutable($date),
plan: $plan, plan: $plan,
node: $node,
) )
); );
} }

View file

@ -7,5 +7,6 @@ class CreateScheduledNodeRequest
public function __construct( public function __construct(
public ?string $date, public ?string $date,
public ?int $planId, public ?int $planId,
public ?int $nodeId,
) {} ) {}
} }

View file

@ -20,6 +20,7 @@ class FakeScheduledNodeRepository implements ScheduledNodeRepository
id: $id, id: $id,
date: $dto->date, date: $dto->date,
plan: $dto->plan, plan: $dto->plan,
node: $dto->node,
); );
$this->existingScheduledNodes[$id] = $scheduledNode; $this->existingScheduledNodes[$id] = $scheduledNode;

View file

@ -45,6 +45,7 @@ class CreatePlanTest extends TestCase
$this->createScheduledNode = new CreateScheduledNode( $this->createScheduledNode = new CreateScheduledNode(
scheduledNodeRepo: $this->scheduledNodeRepo, scheduledNodeRepo: $this->scheduledNodeRepo,
planRepo: $this->planRepo, planRepo: $this->planRepo,
nodeRepo: $this->nodeRepo,
); );
$this->textRepo->create(new CreateTextDto('testname')); $this->textRepo->create(new CreateTextDto('testname'));
$this->useCase = new CreatePlan( $this->useCase = new CreatePlan(

View file

@ -3,15 +3,19 @@
namespace Tests\Unit\ScheduledNode\UseCases; namespace Tests\Unit\ScheduledNode\UseCases;
use App\Exceptions\BadRequestException; use App\Exceptions\BadRequestException;
use App\Node\CreateNodeDto;
use App\Node\Node;
use App\Plan\CreatePlanDto; use App\Plan\CreatePlanDto;
use App\Plan\Plan; use App\Plan\Plan;
use App\ScheduledNode\ScheduledNode; use App\ScheduledNode\ScheduledNode;
use App\ScheduledNode\ScheduledNodeRepository; use App\ScheduledNode\ScheduledNodeRepository;
use App\ScheduledNode\UseCases\CreateScheduledNode; use App\ScheduledNode\UseCases\CreateScheduledNode;
use App\ScheduledNode\UseCases\CreateScheduledNodeRequest; use App\ScheduledNode\UseCases\CreateScheduledNodeRequest;
use App\Text\Text;
use App\User\User; use App\User\User;
use App\ValueObjects\EmailAddress; use App\ValueObjects\EmailAddress;
use DomainException; use DomainException;
use Tests\Fakes\FakeNodeRepository;
use Tests\Fakes\FakePlanRepository; use Tests\Fakes\FakePlanRepository;
use Tests\Fakes\FakeScheduledNodeRepository; use Tests\Fakes\FakeScheduledNodeRepository;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
@ -22,12 +26,20 @@ class CreateScheduledNodeTest extends TestCase
private FakePlanRepository $planRepo; private FakePlanRepository $planRepo;
private FakeNodeRepository $nodeRepo;
private CreateScheduledNode $useCase; private CreateScheduledNode $useCase;
public function setUp(): void public function setUp(): void
{ {
$this->scheduledNodeRepo = new FakeScheduledNodeRepository(); $this->scheduledNodeRepo = new FakeScheduledNodeRepository();
$this->planRepo = new FakePlanRepository(); $this->planRepo = new FakePlanRepository();
$this->nodeRepo = new FakeNodeRepository();
$this->nodeRepo->create(new CreateNodeDto(
text: new Text(0, 'text name'),
title: 'test node',
parentNode: null,
));
$this->planRepo->create(new CreatePlanDto( $this->planRepo->create(new CreatePlanDto(
name: 'testplan', name: 'testplan',
user: new User( user: new User(
@ -40,6 +52,7 @@ class CreateScheduledNodeTest extends TestCase
$this->useCase = new CreateScheduledNode( $this->useCase = new CreateScheduledNode(
$this->scheduledNodeRepo, $this->scheduledNodeRepo,
$this->planRepo, $this->planRepo,
$this->nodeRepo,
); );
} }
@ -49,6 +62,7 @@ class CreateScheduledNodeTest extends TestCase
new CreateScheduledNodeRequest( new CreateScheduledNodeRequest(
date: '2025-01-01', date: '2025-01-01',
planId: 0, planId: 0,
nodeId: 0,
) )
); );
$this->assertInstanceOf(ScheduledNode::class, $scheduledNode); $this->assertInstanceOf(ScheduledNode::class, $scheduledNode);
@ -64,11 +78,24 @@ class CreateScheduledNodeTest extends TestCase
new CreateScheduledNodeRequest( new CreateScheduledNodeRequest(
date: '2025-01-01', date: '2025-01-01',
planId: 0, planId: 0,
nodeId: 0
) )
); );
$this->assertInstanceOf(Plan::class, $scheduledNode->getPlan()); $this->assertInstanceOf(Plan::class, $scheduledNode->getPlan());
} }
public function test_scheduled_node_belongs_to_node(): void
{
$scheduledNode = $this->useCase->execute(
new CreateScheduledNodeRequest(
date: '2025-01-01',
planId: 0,
nodeId: 0
)
);
$this->assertInstanceOf(Node::class, $scheduledNode->getNode());
}
public function test_nonexistant_plan_throws(): void public function test_nonexistant_plan_throws(): void
{ {
$this->expectException(DomainException::class); $this->expectException(DomainException::class);
@ -77,6 +104,20 @@ class CreateScheduledNodeTest extends TestCase
new CreateScheduledNodeRequest( new CreateScheduledNodeRequest(
date: '2025-01-01', date: '2025-01-01',
planId: 1, planId: 1,
nodeId: 0,
)
);
}
public function test_nonexistant_node_throws(): void
{
$this->expectException(DomainException::class);
$this->expectExceptionMessage('Node with id: 1 doesnt exist');
$this->useCase->execute(
new CreateScheduledNodeRequest(
date: '2025-01-01',
planId: 0,
nodeId: 1,
) )
); );
} }
@ -90,6 +131,7 @@ class CreateScheduledNodeTest extends TestCase
new CreateScheduledNodeRequest( new CreateScheduledNodeRequest(
date: null, date: null,
planId: 0, planId: 0,
nodeId: 0
) )
); );
} }
@ -103,6 +145,21 @@ class CreateScheduledNodeTest extends TestCase
new CreateScheduledNodeRequest( new CreateScheduledNodeRequest(
date: '2025-01-01', date: '2025-01-01',
planId: null, planId: null,
nodeId: 0,
)
);
}
public function test_throws_if_node_id_is_null(): void
{
$this->expectException(BadRequestException::class);
$this->expectExceptionMessage('nodeId is required');
$this->useCase->execute(
new CreateScheduledNodeRequest(
date: '2025-01-01',
planId: 0,
nodeId: null,
) )
); );
} }

View file

@ -55,6 +55,7 @@ class PlanControllerTest extends TestCase
$createScheduledNode = new CreateScheduledNode( $createScheduledNode = new CreateScheduledNode(
scheduledNodeRepo: $this->scheduledNodeRepo, scheduledNodeRepo: $this->scheduledNodeRepo,
planRepo: $this->planRepo, planRepo: $this->planRepo,
nodeRepo: $this->nodeRepo,
); );
$this->createPlan = new CreatePlan( $this->createPlan = new CreatePlan(
$this->planRepo, $this->planRepo,