...
 
Commits (2)
<?php
/**
* OnchainBadgeDelegate
*
* @author Ben Hayward
*/
namespace Minds\Core\Boost\Delegates;
use Minds\Core\Boost\Network\Boost;
class OnchainBadgeDelegate
{
/**
* Updates the timestamp of the users 'onchain_booster' to 7 days in the future.
* @param array $boost
*/
public function dispatch(Boost $boost)
{
$user = $boost->getOwner();
$user->setOnchainBooster(time() + 604800); //7 days
$user->save();
}
}
......@@ -8,6 +8,9 @@ use Minds\Entities\Boost\BoostEntityInterface;
use Minds\Entities\Boost\Network;
use Minds\Helpers\MagicAttributes;
use Minds\Interfaces\BoostReviewInterface;
use Minds\Core\Boost\Delegates;
use Minds\Core\Boost\Delegates\OnchainBadgeDelegate;
use MongoDB\BSON;
class Review implements BoostReviewInterface
......@@ -18,16 +21,20 @@ class Review implements BoostReviewInterface
/** @var Manager $manager */
protected $manager;
/** @var OnchainBadgeDelegate $onchainBadge */
protected $onchainBadge;
/** @var Analytics $analaytics */
protected $analytics;
/** @var string $type */
protected $type;
public function __construct($manager = null, $analytics = null)
public function __construct($manager = null, $analytics = null, $onchainBadge = null)
{
$this->manager = $manager ?: new Manager;
$this->analytics = $analytics ?: new Analytics;
$this->onchainBadge = $onchainBadge ?: new OnchainBadgeDelegate;
}
/**
......@@ -64,11 +71,13 @@ class Review implements BoostReviewInterface
}
$success = Core\Di\Di::_()->get('Boost\Payment')->charge($this->boost);
if ($success) {
if ($this->boost->isOnChain()) {
$this->onchainBadge->dispatch($this->boost);
}
$this->boost->setReviewedTimestamp(round(microtime(true) * 1000));
return $this->manager->update($this->boost);
} else {
throw new \Exception('error while accepting the boost');
}
throw new \Exception('error while accepting the boost');
}
/**
......
......@@ -51,6 +51,7 @@ class User extends \ElggUser
$this->attributes['creator_frequency'] = null;
$this->attributes['last_avatar_upload'] = 0;
$this->attributes['canary'] = 0;
$this->attributes['onchain_booster'] = null;
parent::initializeAttributes();
}
......@@ -737,6 +738,7 @@ class User extends \ElggUser
$export['canary'] = (bool) $this->isCanary();
$export['is_admin'] = $this->attributes['admin'] == 'yes';
$export['theme'] = $this->getTheme();
$export['onchain_booster'] = $this->getOnchainBooster();
if (is_string($export['social_profiles'])) {
$export['social_profiles'] = json_decode($export['social_profiles']);
......@@ -985,6 +987,7 @@ class User extends \ElggUser
'last_avatar_upload',
'canary',
'theme',
'onchain_booster'
));
}
......@@ -1044,4 +1047,32 @@ class User extends \ElggUser
return "urn:user:{$this->getGuid()}";
}
/**
* Returns whether the user has onchain_booster status.
* @return boolean true if the date set in onchain_booster is larger than the current time.
*/
public function isOnchainBooster()
{
return (bool) (time() < $this->onchain_booster);
}
/**
* Gets the unix timestamp for the last time the user boosted onchain.
* @return int the date that a booster last boosted on chain
*/
public function getOnchainBooster()
{
return (int) $this->onchain_booster;
}
/**
* Sets the unix timestamp for the last time the user boosted onchain
* @param int $time - the time to set the users onchain_booster variable to.
* @return $this
*/
public function setOnchainBooster($time)
{
$this->onchain_booster = (int) $time;
return $this;
}
}
<?php
/**
* Onchain badge granting delegate spec test.
*
* @author Ben Hayward
*/
namespace Spec\Minds\Core\Boost\Delegates;
use Minds\Core\Boost\Network\Boost;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Minds\Core\Boost\Delegates\OnchainBadgeDelegate;
use Minds\Entities\User;
class OnchainBadgeDelegateSpec extends ObjectBehavior
{
private $user;
function let(User $user)
{
$this->user = $user;
}
function it_is_initializable()
{
$this->shouldHaveType(OnchainBadgeDelegate::class);
}
function it_should_update_a_users_plus_badge_expiry(Boost $boost, User $user)
{
$boost->getOwner()
->shouldBeCalled()
->willReturn($user);
$user->setOnchainBooster(time() + 604800)
->shouldBeCalled()
->willReturn(null);
$user->save()
->shouldBeCalled()
->willReturn(true);
$this->dispatch($boost);
}
}
......@@ -7,18 +7,21 @@ use Minds\Core\Boost\Repository;
use Minds\Core\Boost\Network\Manager;
use Minds\Core\Boost\Network\Boost;
use Minds\Core\Di\Di;
use Minds\Entities\Boost\Network;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Minds\Core\Boost\Delegates\OnchainBadgeDelegate;
use Minds\Entities\User;
class ReviewSpec extends ObjectBehavior
{
private $manager;
private $onchainBadge;
function let(Manager $manager)
function let(Manager $manager, OnchainBadgeDelegate $onchainBadge)
{
$this->beConstructedWith($manager);
$this->beConstructedWith($manager, null, $onchainBadge);
$this->manager = $manager;
$this->onchainBadge = $onchainBadge;
}
function it_is_initializable()
......@@ -50,8 +53,10 @@ class ReviewSpec extends ObjectBehavior
->during('accept');
}
function it_should_accept_a_boost(Payment $payment, Boost $boost)
function it_should_accept_a_boost(Payment $payment, Boost $boost, User $user)
{
$boost->setOwner($user);
Di::_()->bind('Boost\Payment', function ($di) use ($payment) {
return $payment->getWrappedObject();
});
......@@ -69,6 +74,68 @@ class ReviewSpec extends ObjectBehavior
}
function it_should_accept_an_onchain_boost_and_call_onchain_badge_delegate(Payment $payment, Boost $boost)
{
$boost->isOnChain()
->shouldBeCalled()
->willReturn(true);
$boost->setReviewedTimestamp(Argument::approximate(time() * 1000, -4))
->shouldBeCalled()
->willReturn(true);
$this->setBoost($boost);
Di::_()->bind('Boost\Payment', function ($di) use ($payment) {
return $payment->getWrappedObject();
});
$payment->charge(Argument::any())
->shouldBeCalled()
->willReturn(true);
$this->onchainBadge->dispatch($boost)
->shouldBeCalled()
->willReturn(true);
$this->manager->update($boost)
->shouldBeCalled()
->willReturn(true);
$this->accept();
}
function it_should_accept_an_offchain_boost_and_not_call_onchain_badge_delegate(Payment $payment, Boost $boost, User $user)
{
$boost->isOnChain()
->shouldBeCalled()
->willReturn(false);
$boost->setReviewedTimestamp(Argument::approximate(time() * 1000, -4))
->shouldBeCalled()
->willReturn(true);
$this->setBoost($boost);
Di::_()->bind('Boost\Payment', function ($di) use ($payment) {
return $payment->getWrappedObject();
});
$payment->charge(Argument::any())
->shouldBeCalled()
->willReturn(true);
$this->onchainBadge->dispatch($boost)
->shouldNotBeCalled()
->willReturn(true);
$this->manager->update($boost)
->shouldBeCalled()
->willReturn(true);
$this->accept();
}
function it_should_throw_an_exception_when_rejecting_if_boost_isnt_set()
{
$this->shouldThrow(new \Exception('Boost wasn\'t set'))
......@@ -156,7 +223,7 @@ class ReviewSpec extends ObjectBehavior
Di::_()->bind('Boost\Repository', function ($di) use ($repository) {
return $repository->getWrappedObject();
});
$repository->getAll('newsfeed', Argument::is([
'owner_guid' => '123',
'limit' => 12,
......
......@@ -35,4 +35,18 @@ class UserSpec extends ObjectBehavior
$this->isAdmin()->shouldBe(true);
}
function it_should_assign_the_onchain_booster_status() {
$this->setOnchainBooster(123);
$this->getOnchainBooster()->shouldReturn(123);
}
function it_should_recognise_a_user_is_in_the_onchain_booster_timeframe() {
$this->setOnchainBooster(20601923579999);
$this->isOnchainBooster()->shouldReturn(true);
}
function it_should_recognise_a_user_is_not_in_the_onchain_booster_timeframe() {
$this->setOnchainBooster(1560192357);
$this->isOnchainBooster()->shouldReturn(false);
}
}