Skip to content

Commit

Permalink
Subscription Manager compoenent
Browse files Browse the repository at this point in the history
  • Loading branch information
kadet1090 committed Mar 5, 2017
1 parent b210e52 commit f6cba5a
Show file tree
Hide file tree
Showing 7 changed files with 220 additions and 7 deletions.
3 changes: 3 additions & 0 deletions Component/Component.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,8 @@ abstract class Component implements ComponentInterface
public function setClient(XmppClient $client)
{
$this->_client = $client;
$this->init();
}

protected function init() { }
}
2 changes: 1 addition & 1 deletion Component/PingKeepAlive.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class PingKeepAlive extends Component
*
* @param float|false $interval Keep alive interval in seconds or false to turn off
*/
public function __construct($interval = 15.)
public function __construct($interval = 60.)
{
$this->_interval = $interval;
}
Expand Down
85 changes: 85 additions & 0 deletions Component/Subscription/SubscriptionManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php
/**
* Nucleus - XMPP Library for PHP
*
* Copyright (C) 2017, Some rights reserved.
*
* @author Kacper "Kadet" Donat <[email protected]>
*
* Contact with author:
* Xmpp: [email protected]
* E-mail: [email protected]
*
* From Kadet with love.
*/

namespace Kadet\Xmpp\Component\Subscription;


use Kadet\Xmpp\Component\Component;
use Kadet\Xmpp\Jid;
use Kadet\Xmpp\Stanza\Presence;
use Kadet\Xmpp\Utils\BetterEmitter;

use function \Kadet\Xmpp\Utils\filter\{
stanza\type, in
};

class SubscriptionManager extends Component
{
use BetterEmitter;

protected function init()
{
$this->_client->on('presence', function(...$args) {
$this->handleSubscriptionRequest(...$args);
}, type('subscribe'));
}

private function handleSubscriptionRequest(Presence $presence)
{
$this->emit('request', [ $presence ]);
}

/**
* Sends subscription request presence to server.
*
* @param Jid|string $jid
* @return \React\Promise\ExtendedPromiseInterface
*/
public function subscribe($jid)
{
return $this->_client->send($this->presence('subscribe', $jid));
}

/**
* Sends subscription removal request presence to server.
*
* @param Jid|string $jid
* @return \React\Promise\ExtendedPromiseInterface
*/
public function unsubscribe(Jid $jid)
{
return $this->_client->send($this->presence('unsubscribe', $jid));
}

/**
* Sends subscription cancellation request presence to server.
*
* @param Jid|string $jid
* @return \React\Promise\ExtendedPromiseInterface
*/
public function cancel($jid)
{
return $this->_client->send($this->presence('unsubscribed', $jid));
}

private function presence($type, $jid)
{
$jid = $jid instanceof Jid ? $jid : new Jid($jid);
return new Presence([
'type' => $type,
'to' => $jid->bare()
]);
}
}
8 changes: 3 additions & 5 deletions Component/TlsEnabler.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,13 @@

class TlsEnabler extends Component
{
public function setClient(XmppClient $client)
public function init()
{
parent::setClient($client);

$client->on('features', function (Features $features) {
$this->_client->on('features', function (Features $features) {
return !$this->startTls($features);
}, null, 10);

$client->on('element', function (XmlElement $element) {
$this->_client->on('element', function (XmlElement $element) {
return $this->handleTls($element);
}, with\element\xmlns(Features\StartTls::XMLNS));
}
Expand Down
13 changes: 13 additions & 0 deletions Stanza/Presence.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
namespace Kadet\Xmpp\Stanza;

use Kadet\Xmpp\Exception\InvalidArgumentException;
use Kadet\Xmpp\Jid;
use Kadet\Xmpp\Utils\filter;
use Kadet\Xmpp\Xml\XmlElement;

Expand All @@ -35,6 +36,18 @@ class Presence extends Stanza
{
const POSSIBLE_SHOW = ['available', 'unavailable', 'chat', 'dnd', 'away', 'xa'];

/**
* Presence constructor.
* @param array $options {
* @var Jid $from Jid representing "from" stanza attribute
* @var Jid $to Jid representing "to" stanza attribute
* @var string $id Unique id, will be generated if omitted
* @var string $type Stanza type
* @var string $show
* @var string status
* @var int $priority
* }
*/
public function __construct(array $options = [])
{
parent::__construct('presence', $options);
Expand Down
113 changes: 113 additions & 0 deletions Tests/Modules/Subscription/SubscriptionManagerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<?php
/**
* Nucleus - XMPP Library for PHP
*
* Copyright (C) 2017, Some rights reserved.
*
* @author Kacper "Kadet" Donat <[email protected]>
*
* Contact with author:
* Xmpp: [email protected]
* E-mail: [email protected]
*
* From Kadet with love.
*/

namespace Kadet\Xmpp\Tests\Modules\Subscription;


use Kadet\Xmpp\Component\Subscription\SubscriptionManager;
use Kadet\Xmpp\Jid;
use Kadet\Xmpp\Stanza\Presence;
use Kadet\Xmpp\Tests\Stubs\ConnectorStub;
use Kadet\Xmpp\XmppClient;
use PHPUnit_Framework_MockObject_MockObject as Mock;

use function Kadet\Xmpp\Utils\filter\{
all, not, pass
};
use function Kadet\Xmpp\Utils\filter\stanza\{
to, type, id
};

class SubscriptionManagerTest extends \PHPUnit_Framework_TestCase
{
/**
* @var XmppClient|Mock
*/
private $_client;

/**
* @var SubscriptionManager
*/
private $_manager;

/**
* @return XmppClient|Mock
*/
public function getMockClient()
{
return $this->getMockBuilder(XmppClient::class)
->setConstructorArgs([new Jid('local@domain'), [
'connector' => new ConnectorStub(),
'default-modules' => false,
'modules' => [
$this->_manager = new SubscriptionManager()
]
]])->setMethods(['write'])
->getMock();
}

protected function setUp()
{
$this->_client = $this->getMockClient();
}

public function testSubscriptionRequest()
{
$jid = new Jid('[email protected]');

$this->_client->expects($this->once())->method('write')->withConsecutive($this->callback(all(
type('subscribe'), id(not(null)), to((string)$jid->bare())
)));

$this->_manager->subscribe($jid);
}


public function testSubscriptionRequestEvent()
{
$jid = new Jid('[email protected]');

$presence = new Presence(['type' => 'subscribe', 'from' => $jid]);

$mock = $this->getMockBuilder('stdClass')->setMethods(['predicate'])->getMock();
$mock->expects($this->once())->method('predicate')->withConsecutive($presence);

$this->_manager->on('request', [$mock, 'predicate']);
$this->_client->emit('element', [ $presence ]);
}

public function testSubscriptionRemovalRequest()
{
$jid = new Jid('[email protected]');

$this->_client->expects($this->once())->method('write')->withConsecutive($this->callback(all(
type('unsubscribe'), id(not(null)), to((string)$jid->bare())
)));

$this->_manager->unsubscribe($jid);
}


public function testSubscriptionCancellation()
{
$jid = new Jid('[email protected]');

$this->_client->expects($this->once())->method('write')->withConsecutive($this->callback(all(
type('unsubscribed'), id(not(null)), to((string)$jid->bare())
)));

$this->_manager->cancel($jid);
}
}
3 changes: 2 additions & 1 deletion Utils/filter.php
Original file line number Diff line number Diff line change
Expand Up @@ -319,8 +319,9 @@ function predicate($predicate, bool $strict = false) : \Closure
* @param callable $predicate
* @return \Closure
*/
function not(callable $predicate) : \Closure
function not($predicate) : \Closure
{
$predicate = predicate($predicate);
return function (...$arguments) use ($predicate) {
return !$predicate(...$arguments);
};
Expand Down

0 comments on commit f6cba5a

Please sign in to comment.