Skip to content

Commit

Permalink
Add Bitrix24Account entity and unit tests
Browse files Browse the repository at this point in the history
This commit introduces the `Bitrix24Account` entity with full implementation for managing Bitrix24 account statuses, auth tokens, and domain URLs. It also includes unit tests for the added entity, and updates the `composer.json` to reflect changes in namespace configurations.

Signed-off-by: mesilov <[email protected]>
  • Loading branch information
mesilov committed Sep 1, 2024
1 parent 13b8c10 commit c28b8bd
Show file tree
Hide file tree
Showing 3 changed files with 360 additions and 3 deletions.
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
"doctrine/doctrine-migrations-bundle": "^3",
"symfony/event-dispatcher": "^7",
"symfony/uid": "^7",
"symfony/uid": "^7",
"knplabs/knp-paginator-bundle": "^6"
},
"require-dev": {
Expand All @@ -57,12 +56,13 @@
},
"autoload": {
"psr-4": {
"Mesilov\\Bitrix24\\ApplicationCore\\": "src"
"Bitrix24\\SDK\\ApplicationCore\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"Mesilov\\Bitrix24\\ApplicationCore\\Tests\\": "tests"
"Bitrix24\\SDK\\ApplicationCore\\Tests\\": "tests",
"Bitrix24\\SDK\\Tests\\":"vendor/mesilov/bitrix24-php-sdk/tests"
}
}
}
298 changes: 298 additions & 0 deletions src/Bitrix24Accounts/Entity/Bitrix24Account.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,298 @@
<?php
/**
* This file is part of the bitrix24-app-core package.
*
* © Maksim Mesilov <[email protected]>
*
* For the full copyright and license information, please view the MIT-LICENSE.txt
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Bitrix24\SDK\ApplicationCore\Bitrix24Accounts\Entity;

use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountInterface;
use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus;
use Bitrix24\SDK\Core\Credentials\AuthToken;
use Bitrix24\SDK\Core\Credentials\Scope;
use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException;
use Bitrix24\SDK\Core\Exceptions\UnknownScopeCodeException;
use Bitrix24\SDK\Core\Response\DTO\RenewedAuthToken;
use Carbon\CarbonImmutable;
use Symfony\Component\Uid\Uuid;

class Bitrix24Account implements Bitrix24AccountInterface
{
private string $accessToken;

private string $refreshToken;

private int $expires;

private array $applicationScope;

private ?string $applicationToken = null;

private ?string $comment = null;

public function __construct(
private readonly Uuid $id,
private readonly int $bitrix24UserId,
private readonly bool $isBitrix24UserAdmin,
private readonly string $memberId,
private string $domainUrl,
private Bitrix24AccountStatus $accountStatus,
AuthToken $authToken,
private readonly CarbonImmutable $createdAt,
private CarbonImmutable $updatedAt,
private int $applicationVersion,
Scope $applicationScope,
)
{
$this->accessToken = $authToken->getAccessToken();
$this->refreshToken = $authToken->getRefreshToken();
$this->expires = $authToken->getExpires();
$this->applicationScope = $applicationScope->getScopeCodes();
}

#[\Override]
public function getId(): Uuid
{
return $this->id;
}

#[\Override]
public function getBitrix24UserId(): int
{
return $this->bitrix24UserId;
}

#[\Override]
public function isBitrix24UserAdmin(): bool
{
return $this->isBitrix24UserAdmin;
}

#[\Override]
public function getMemberId(): string
{
return $this->memberId;
}

#[\Override]
public function getDomainUrl(): string
{
return $this->domainUrl;
}

#[\Override]
public function getStatus(): Bitrix24AccountStatus
{
return $this->accountStatus;
}

#[\Override]
public function getAuthToken(): AuthToken
{
return new AuthToken($this->accessToken, $this->refreshToken, $this->expires);
}

/**
* @throws InvalidArgumentException
*/
#[\Override]
public function renewAuthToken(RenewedAuthToken $renewedAuthToken): void
{
if ($this->memberId !== $renewedAuthToken->memberId) {
throw new InvalidArgumentException(
sprintf(
'member id %s for bitrix24 account %s for domain %s mismatch with member id %s for renewed access token',
$this->memberId,
$this->id->toRfc4122(),
$this->domainUrl,
$renewedAuthToken->memberId,
)
);
}

$this->accessToken = $renewedAuthToken->authToken->getAccessToken();
$this->refreshToken = $renewedAuthToken->authToken->getRefreshToken();
$this->expires = $renewedAuthToken->authToken->getExpires();
$this->updatedAt = new CarbonImmutable();
}

#[\Override]
public function getApplicationVersion(): int
{
return $this->applicationVersion;
}

/**
* @throws UnknownScopeCodeException
*/
#[\Override]
public function getApplicationScope(): Scope
{
return new Scope($this->applicationScope);
}

/**
* @throws InvalidArgumentException
*/
#[\Override]
public function changeDomainUrl(string $newDomainUrl): void
{
if ($newDomainUrl === '') {
throw new InvalidArgumentException('new domain url cannot be empty');
}

if (Bitrix24AccountStatus::blocked === $this->accountStatus || Bitrix24AccountStatus::deleted === $this->accountStatus) {
throw new InvalidArgumentException(
sprintf(
'bitrix24 account %s for domain %s must be in active or new state, now account in %s state. domain url cannot be changed',
$this->id->toRfc4122(),
$this->domainUrl,
$this->accountStatus->name
)
);
}

$this->domainUrl = $newDomainUrl;
$this->updatedAt = new CarbonImmutable();
}

/**
* @throws InvalidArgumentException
*/
#[\Override]
public function applicationInstalled(string $applicationToken): void
{
if (Bitrix24AccountStatus::new !== $this->accountStatus) {
throw new InvalidArgumentException(sprintf(
'for finish installation bitrix24 account must be in status «new», current status - «%s»',
$this->accountStatus->name));
}

if ($applicationToken === '') {
throw new InvalidArgumentException('application token cannot be empty');
}

$this->accountStatus = Bitrix24AccountStatus::active;
$this->applicationToken = $applicationToken;
$this->updatedAt = new CarbonImmutable();
}

/**
* @throws InvalidArgumentException
*/
#[\Override]
public function applicationUninstalled(string $applicationToken): void
{
if ($applicationToken === '') {
throw new InvalidArgumentException('application token cannot be empty');
}

if (Bitrix24AccountStatus::active !== $this->accountStatus) {
throw new InvalidArgumentException(sprintf(
'for uninstall account must be in status «active», current status - «%s»',
$this->accountStatus->name));
}

if ($this->applicationToken !== $applicationToken) {
throw new InvalidArgumentException(
sprintf(
'application token «%s» mismatch with application token «%s» for bitrix24 account %s for domain %s',
$applicationToken,
$this->applicationToken,
$this->id->toRfc4122(),
$this->domainUrl
)
);
}

$this->accountStatus = Bitrix24AccountStatus::deleted;
$this->updatedAt = new CarbonImmutable();
}

#[\Override]
public function isApplicationTokenValid(string $applicationToken): bool
{
return $this->applicationToken === $applicationToken;
}

#[\Override]
public function getCreatedAt(): CarbonImmutable
{
return $this->createdAt;
}

#[\Override]
public function getUpdatedAt(): CarbonImmutable
{
return $this->updatedAt;
}

/**
* @throws InvalidArgumentException
*/
#[\Override]
public function updateApplicationVersion(int $version, ?Scope $newScope): void
{
if (Bitrix24AccountStatus::active !== $this->accountStatus) {
throw new InvalidArgumentException(sprintf('account must be in status «active», but now account in status «%s»', $this->accountStatus->name));
}

if ($this->applicationVersion >= $version) {
throw new InvalidArgumentException(
sprintf('you cannot downgrade application version or set some version, current version «%s», but you try to upgrade to «%s»',
$this->applicationVersion,
$version));
}

$this->applicationVersion = $version;
if ($newScope instanceof \Bitrix24\SDK\Core\Credentials\Scope) {
$this->applicationScope = $newScope->getScopeCodes();
}

$this->updatedAt = new CarbonImmutable();
}

/**
* @throws InvalidArgumentException
*/
#[\Override]
public function markAsActive(?string $comment): void
{
if (Bitrix24AccountStatus::blocked !== $this->accountStatus) {
throw new InvalidArgumentException(
sprintf('you can activate account only in status blocked, now account in status %s',
$this->accountStatus->name));
}

$this->accountStatus = Bitrix24AccountStatus::active;
$this->comment = $comment;
$this->updatedAt = new CarbonImmutable();
}

/**
* @throws InvalidArgumentException
*/
#[\Override]
public function markAsBlocked(?string $comment): void
{
if (Bitrix24AccountStatus::deleted === $this->accountStatus) {
throw new InvalidArgumentException('you cannot block account in status «deleted»');
}

$this->accountStatus = Bitrix24AccountStatus::blocked;
$this->comment = $comment;
$this->updatedAt = new CarbonImmutable();
}

#[\Override]
public function getComment(): ?string
{
return $this->comment;
}
}
59 changes: 59 additions & 0 deletions tests/Unit/Bitrix24Accounts/Entity/Bitrix24AccountTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

/**
* This file is part of the bitrix24-app-core package.
*
* © Maksim Mesilov <[email protected]>
*
* For the full copyright and license information, please view the MIT-LICENSE.txt
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Bitrix24\SDK\ApplicationCore\Tests\Unit\Bitrix24Accounts\Entity;

use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountInterface;
use Bitrix24\SDK\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountStatus;
use Bitrix24\SDK\ApplicationCore\Bitrix24Accounts\Entity\Bitrix24Account;
use Bitrix24\SDK\Core\Credentials\AuthToken;
use Bitrix24\SDK\Core\Credentials\Scope;
use Bitrix24\SDK\Tests\Application\Contracts\Bitrix24Accounts\Entity\Bitrix24AccountInterfaceTest;
use Carbon\CarbonImmutable;
use Override;
use PHPUnit\Framework\Attributes\CoversClass;
use Symfony\Component\Uid\Uuid;

#[CoversClass(Bitrix24Account::class)]
class Bitrix24AccountTest extends Bitrix24AccountInterfaceTest
{
#[Override]
protected function createBitrix24AccountImplementation(
Uuid $uuid,
int $bitrix24UserId,
bool $isBitrix24UserAdmin,
string $memberId,
string $domainUrl,
Bitrix24AccountStatus $bitrix24AccountStatus,
AuthToken $authToken,
CarbonImmutable $createdAt,
CarbonImmutable $updatedAt,
int $applicationVersion,
Scope $applicationScope
): Bitrix24AccountInterface
{
return new Bitrix24Account(
$uuid,
$bitrix24UserId,
$isBitrix24UserAdmin,
$memberId,
$domainUrl,
$bitrix24AccountStatus,
$authToken,
$createdAt,
$updatedAt,
$applicationVersion,
$applicationScope
);
}
}

0 comments on commit c28b8bd

Please sign in to comment.