Commit a0b6deb6 authored by Mark Harding's avatar Mark Harding

(feat): spec tests and delegate for manager

1 merge request!327WIP: Subscription Requests - #604
Pipeline #82523945 running with stages
<?php
namespace Minds\Core\Subscriptions\Requests\Delegates;
use Minds\Core\Subscriptions\Requests\SubscriptionRequest;
class NotificationsDelegate
{
/**
* Called when subscription request is made
* @param SubscriptionRequest $subscriptionRequest
* @return void
*/
public function onAdd(SubscriptionRequest $subscriptionRequest): void
{
// TODO
}
/**
* Called when subscription request is accepted
* @param SubscriptionRequest $subscriptionRequest
* @return void
*/
public function onAccept(SubscriptionRequest $subscriptionRequest): void
{
// TODO
}
/**
* Called when subscription request is declined
* @param SubscriptionRequest $subscriptionRequest
* @return void
*/
public function onDecline(SubscriptionRequest $subscriptionRequest): void
{
// TODO
}
}
<?php
namespace Minds\Core\Subscriptions\Requests\Delegates;
use Minds\Core\Subscriptions\Requests\SubscriptionRequest;
class SubscriptionsDelegate
{
/**
* Called when subscription request is accepted
* @param SubscriptionRequest $subscriptionRequest
* @return void
*/
public function onAccept(SubscriptionRequest $subscriptionRequest): void
{
// TODO
}
}
......@@ -4,25 +4,117 @@
*/
namespace Minds\Core\Subscriptions\Requests;
use Minds\Core\Subscriptions\Requests\Delegates\NotificationsDelegate;
use Minds\Core\Subscriptions\Requests\Delegates\SubscriptionsDelegate;
use Minds\Common\Repository\Response;
class Manager
{
/** @var Repository */
private $repository;
/** @var NotificationsDelegate */
private $notificationsDelegate;
/** @var SubscriptionsDelegate */
private $subscriptionsDelegate;
public function __construct($repository = null, $notificationsDelegate = null, $subscriptionsDelegate = null)
{
$this->repository = $repository ?? new Repository();
$this->notificationsDelegate = $notificationsDelegate ?? new NotificationsDelegate;
$this->subscriptionsDelegate = $subscriptionsDelegate ?? new SubscriptionsDelegate;
}
/**
* Return a list of incoming subscription requests
* @param array $opts
* @return Response
*/
public function getIncomingList(array $opts = [])
{
$response = $this->repository->getList($opts);
return $response;
}
/**
* Return a subscription request
* @param string $urn
* @return SubscriptionRequest
*/
public function get(string $urn): ?SubscriptionRequest
{
return $this->repository->get($urn);
}
/**
* Add a subscription request
* @param SubscriptionRequest $subscriptionRequest
* @return bool
*/
public function add(SubscriptionRequest $subscriptionRequest): bool
{
// Check if exists
$existing = $this->get($subscriptionRequest->getUrn());
if ($existing) {
throw new SubscriptionRequestExistsException();
}
$this->repository->add($subscriptionRequest);
$this->notificationsDelegate->onAdd($subscriptionRequest);
return true;
}
/**
* Accept a subscription request
* @param SubscriptionRequest $subscriptionRequest
* @return bool
*/
public function accept(SubscriptionRequest $subscriptionRequest): bool
{
// Check if exists
$existing = $this->get($subscriptionRequest->getUrn());
if (!$existing) {
throw new SubscriptionRequestDoesntExistException();
}
if ($existing->getAccepted() !== null) {
throw new SubscriptionRequestAlreadyCompletedException();
}
$subscriptionRequest->setAccepted(true);
$this->repository->add($subscriptionRequest);
$this->repository->update($subscriptionRequest);
$this->notificationsDelegate->onAccept($subscriptionRequest);
$this->subscriptionsDelegate->onAccept($subscriptionRequest);
return true;
}
/**
* Decline a subscription request
* @param SubscriptionRequest $subscriptionRequest
* @return bool
*/
public function decline(SubscriptionRequest $subscriptionRequest): bool
{
// Check if exists
$existing = $this->get($subscriptionRequest->getUrn());
if (!$existing) {
throw new SubscriptionRequestDoesntExistException();
}
if ($existing->getAccepted() !== null) {
throw new SubscriptionRequestAlreadyCompletedException();
}
$subscriptionRequest->setAccepted(false);
$this->repository->add($subscriptionRequest);
$this->repository->update($subscriptionRequest);
$this->notificationsDelegate->onDecline($subscriptionRequest);
return true;
}
}
<?php
/**
* Subscriptions Requests Repository
*/
namespace Minds\Core\Subscriptions\Requests;
use Minds\Core\Di\Di;
use Minds\Core\Data\Cassandra\Client;
use Minds\Common\Repository\Response;
class Repository
{
/** @var Client */
private $db;
public function __construct($db = null)
{
$this->db = $db ?? Di::_()->get('Database\Cassandra\Cql');
}
/**
* Return a list of subscription requests
* @param array $opts
* @return Response
*/
public function getList(array $opts = []): Response
{
$prepared = new Prepared\Custom();
$prepared->query(
"SELECT * FROM subscription_requests
WHERE publisher_guid = ?",
[
$opts['publisher_guid'],
]
);
$result = $this->db->request($prepared);
$response = new Response;
foreach ($result as $row) {
$subscriptionRequest = new SubscriptionRequest();
$subscriptionRequest
->setPublisherGuid((string) $row['publisher_guid'])
->setSubscriberGuid((string) $row['subscriber_guid'])
->setAccepted((bool) $row['accepted'])
->setTimestampMs((int) $row['timestamp']->time());
$result[] = $subscriptionRequest;
}
return $response;
}
/**
* Return a single subscription request from a urn
* @param string $urn
* @return SubscriptionRequest
*/
public function get(string $urn): ?SubscriptionRequest
{
$urn = new Urn($urn);
list($publisherGuid, $subscriberGuid) = explode('-', $urn->getNss());
$prepared = new Prepared\Custom();
$prepared->query(
"SELECT * FROM subscription_requests
WHERE publisher_guid = ?
AND subscriber_guid = ?",
[
$publisherGuid,
$subscriberGuid,
]
);
$result = $this->db->request($prepared);
if (!$result) {
return null;
}
$row = $result[0];
$subscriptionRequest = new SubscriptionRequest();
$subscriptionRequest
->setPublisherGuid((string) $row['publisher_guid'])
->setSubscriberGuid((string) $row['subscriber_guid'])
->setAccepted((bool) $row['accepted'])
->setTimestampMs((int) $row['timestamp']->time());
return $subscriptionRequest;
}
/**
* Add a subscription request
* @param SubscriptionRequest $subscriptionRequest
* @return bool
*/
public function add(SubscriptionRequest $subscriptionRequest): bool
{
$statement = "INSERT INTO subscription_requests (publisher_guid, subscriber_guid, timestamp) VALUES (?, ?, ?)";
$values = [
new Bigint($subscriptionRequest->getPublisherGuid()),
new Bigint($subscriptionRequest->getSubscriberGuid()),
new Timestamp($subscriptionRequest->getTimestamp() ?? round(microtime(true) * 1000)),
];
$prepared = new Custom\Prepared();
$prepared->query($statement, $values);
return (bool) $this->db->request($prepared);
}
/**
* Update a subscription request
* @param SubscriptionRequest $subscriptionRequest
* @param array $fields
* @return bool
*/
public function update(SubscriptionRequest $subscriptionRequest, array $field = []): bool
{
$statement = "INSERT INTO subscription_requests (publisher_guid, subscriber_guid, timestamp) VALUES (?, ?, ?)";
$values = [
new Bigint($subscriptionRequest->getPublisherGuid()),
new Bigint($subscriptionRequest->getSubscriberGuid()),
new Timestamp($subscriptionRequest->getTimestamp() ?? round(microtime(true) * 1000)),
];
$prepared = new Custom\Prepared();
$prepared->query($statement, $values);
return (bool) $this->db->request($prepared);
}
/**
* Delete a subscription request
* @param SubscriptionRequest $subscriptionRequest
* @return bool
*/
public function delete(SubscriptionRequest $subscriptionRequest): bool
{
$statement = "DELETE FROM subscription_requests
WHERE publisher_guid = ?
AND subscriber_guid = ?";
$values = [
new Bigint($subscriptionRequest->getPublisherGuid()),
new Bigint($subscriptionRequest->getSubscriberGuid()),
];
$prepared = new Custom\Prepared();
$prepared->query($statement, $values);
return (bool) $this->db->request($prepared);
}
}
......@@ -18,7 +18,7 @@ use Minds\Traits\MagicAttributes;
*/
class SubscriptionRequest
{
use MagicAttibutes;
use MagicAttributes;
/** @var string */
private $publisherGuid;
......@@ -27,11 +27,19 @@ class SubscriptionRequest
private $subscriberGuid;
/** @var bool */
private $accepted = false;
private $accepted;
/** @var int */
private $timestampMs;
/**
* @return string
*/
public function getUrn(): string
{
return "urn:subscription-request:" . implode('-', [ $this->publisherGuid, $this->subscriberGuid ]);
}
/**
* Export
* @return array
......
<?php
namespace Spec\Minds\Core\Subscriptions\Requests\Delegates;
use Minds\Core\Subscriptions\Requests\Delegates\SubscriptionsDelegate;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class SubscriptionsDelegateSpec extends ObjectBehavior
{
public function it_is_initializable()
{
$this->shouldHaveType(SubscriptionsDelegate::class);
}
}
<?php
namespace Spec\Minds\Core\Subscriptions\Requests;
use Minds\Core\Subscriptions\Requests\Manager;
use Minds\Core\Subscriptions\Requests\Repository;
use Minds\Core\Subscriptions\Requests\SubscriptionRequest;
use Minds\Core\Subscriptions\Requests\Delegates;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ManagerSpec extends ObjectBehavior
{
private $repository;
private $notificationsDelegate;
private $subscriptionsDelegate;
public function let(
Repository $repository,
Delegates\NotificationsDelegate $notificationsDelegate,
Delegates\SubscriptionsDelegate $subscriptionsDelegate
) {
$this->beConstructedWith($repository, $notificationsDelegate, $subscriptionsDelegate);
$this->repository = $repository;
$this->notificationsDelegate = $notificationsDelegate;
$this->subscriptionsDelegate = $subscriptionsDelegate;
}
public function it_is_initializable()
{
$this->shouldHaveType(Manager::class);
}
public function it_should_add_a_request()
{
$subscriptionRequest = new SubscriptionRequest();
$subscriptionRequest->setPublisherGuid(123)
->setSubscriberGuid(456);
$this->repository->get("urn:subscription-request:123-456")
->willReturn(null);
$this->repository->add($subscriptionRequest)
->willReturn(true);
$this->notificationsDelegate->onAdd($subscriptionRequest)
->shouldBeCalled();
$this->add($subscriptionRequest)
->shouldBe(true);
}
public function it_should_accept_a_request()
{
$subscriptionRequest = new SubscriptionRequest();
$subscriptionRequest->setPublisherGuid(123)
->setSubscriberGuid(456);
$this->repository->get("urn:subscription-request:123-456")
->willReturn($subscriptionRequest);
$this->repository->update(Argument::that(function ($sr) {
return $sr->getAccepted() === true;
}))
->willReturn(true);
$this->notificationsDelegate->onAccept($subscriptionRequest)
->shouldBeCalled();
$this->subscriptionsDelegate->onAccept($subscriptionRequest)
->shouldBeCalled();
$this->accept($subscriptionRequest)
->shouldBe(true);
}
public function it_should_decline_a_request()
{
$subscriptionRequest = new SubscriptionRequest();
$subscriptionRequest->setPublisherGuid(123)
->setSubscriberGuid(456);
$this->repository->get("urn:subscription-request:123-456")
->willReturn($subscriptionRequest);
$this->repository->update(Argument::that(function ($sr) {
return $sr->getAccepted() === false;
}))
->willReturn(true);
$this->notificationsDelegate->onDecline($subscriptionRequest)
->shouldBeCalled();
$this->decline($subscriptionRequest)
->shouldBe(true);
}
}
<?php
namespace Spec\Minds\Core\Subscriptions\Requests;
use Minds\Core\Subscriptions\Requests\Repository;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class RepositorySpec extends ObjectBehavior
{
public function it_is_initializable()
{
$this->shouldHaveType(Repository::class);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment