Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions .tasks/468/plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Plan: Refactor uniqueness check in Bitrix24PartnerRepository test contract (issue #468)

## Context

Issue #468 targets repository contract tests, not a Bitrix24 REST API method. The required
OpenAPI preflight was still executed through `make oa-schema-build` before the issue work.

`Bitrix24PartnerRepositoryInterfaceTest::testSaveWithTwoBitrix24PartnerNumber()` currently
requires every repository implementation to reject duplicate `bitrix24PartnerNumber` values
inside `save()`. That makes `save()` responsible for a business invariant that belongs in
an application/use-case command handler. The repository should stay focused on persistence;
database-level unique constraints remain the final safety net for duplicate writes.

The plan follows the issue acceptance criterion and keeps the change scoped to the partner
repository contract surface:

- remove the duplicate-number contract test
- remove the duplicate-number check from the in-memory contract implementation so the test
double no longer documents that behavior
- remove the `@throws InvalidArgumentException` annotation from `save()` in the repository
interface and fake implementation
- record the behavior change in `CHANGELOG.md`

No Bitrix24 REST methods are added or changed, so the official REST documentation lookup is
not applicable for this issue.

---

## Files to Create

No production or test files need to be created.

---

## Files to Modify

### 1. `tests/Application/Contracts/Bitrix24Partners/Repository/Bitrix24PartnerRepositoryInterfaceTest.php`

Remove the entire `testSaveWithTwoBitrix24PartnerNumber()` method. Keep the remaining
contract tests unchanged:

- `testSave()` continues to assert that `save()` persists one partner
- `testFindByBitrix24PartnerNumber()` continues to assert lookup behavior
- no contract test expects `save()` to query for duplicates or throw on duplicate partner
numbers

### 2. `tests/Unit/Application/Contracts/Bitrix24Partners/Repository/InMemoryBitrix24PartnerRepositoryImplementation.php`

Remove the duplicate-number preflight from `save()`:

```php
$existsPartner = $this->findByBitrix24PartnerNumber($bitrix24Partner->getBitrix24PartnerNumber());
if ($existsPartner instanceof Bitrix24PartnerInterface && $existsPartner->getId() !== $bitrix24Partner->getId()) {
throw new InvalidArgumentException(sprintf(
'bitrix24 partner «%s» with bitrix24 partner number is «%s» already exists with id «%s» in status «%s»',
$existsPartner->getTitle(),
$bitrix24Partner->getBitrix24PartnerNumber(),
$existsPartner->getId(),
$existsPartner->getStatus()->name
));
}
```

After the change, `save()` only logs and stores the partner by UUID:

```php
$this->items[$bitrix24Partner->getId()->toRfc4122()] = $bitrix24Partner;
```

Remove the `@throws InvalidArgumentException` docblock from `save()`. Keep the import because
`findByTitle()` and `findByExternalId()` still throw that exception for empty input.

### 3. `src/Application/Contracts/Bitrix24Partners/Repository/Bitrix24PartnerRepositoryInterface.php`

Remove the `@throws InvalidArgumentException` annotation from `save()`. Keep the import because
`findByTitle()` and `findByExternalId()` still declare this exception.

### 4. `CHANGELOG.md`

Add this entry under `## 3.2.0 – UNRELEASED` → `### Changed`:

```markdown
- Removed the duplicate `bitrix24PartnerNumber` uniqueness expectation from the `Bitrix24PartnerRepositoryInterface` contract so `save()` remains a persistence operation; uniqueness validation belongs in the use-case layer ([#468](https://github.com/bitrix24/b24phpsdk/issues/468))
```

---

## Deptrac compliance

The change only removes test-contract behavior and a test-double preflight. No new classes,
imports, dependencies, or layer references are introduced, so no new Deptrac edge is expected.

---

## Verification

```bash
make test-file path=tests/Unit/Application/Contracts/Bitrix24Partners/Repository
make lint-cs-fixer
make lint-rector
make lint-phpstan
make lint-deptrac
make test-unit
```

No integration suite is required because the issue touches an application contract unit test
and an in-memory unit-test implementation only.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

### Changed

- Removed the duplicate `bitrix24PartnerNumber` uniqueness expectation from the `Bitrix24PartnerRepositoryInterface` contract so `save()` remains a persistence operation; uniqueness validation belongs in the use-case layer ([#468](https://github.com/bitrix24/b24phpsdk/issues/468))
- Removed dead `delete(Uuid $uuid)` method from `Bitrix24PartnerRepositoryInterface`, its in-memory stub implementation, and the `testDelete` contract test — the soft-delete flow (`markAsDeleted()` + `save()`) makes this method redundant ([#471](https://github.com/bitrix24/b24phpsdk/issues/471))
- Replaced `set*` prefix with `change*` in `Bitrix24PartnerInterface` mutator methods (`changeTitle`, `changeSite`, `changePhone`, `changeEmail`, `changeOpenLineId`, `changeExternalId`) to better express domain-level change operations ([#453](https://github.com/bitrix24/b24phpsdk/issues/453))
- Deprecated passing `ATTACH` as raw JSON `string` to `im.message.add` and `im.message.update`; prefer `AttachPayloadInterface` for typed object payloads or raw `array` payloads for backward-compatible structures ([#426](https://github.com/bitrix24/b24phpsdk/issues/426))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ interface Bitrix24PartnerRepositoryInterface
{
/**
* Save bitrix24 partner to persistence storage
* @throws InvalidArgumentException
*/
public function save(Bitrix24PartnerInterface $bitrix24Partner): void;

Expand Down Expand Up @@ -61,4 +60,4 @@ public function findByTitle(string $title): array;
* @throws InvalidArgumentException
*/
public function findByExternalId(string $externalId, ?Bitrix24PartnerStatus $bitrix24PartnerStatus = null): array;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,40 +79,6 @@ final public function testSave(
$this->assertEquals($b24Partner, $res);
}

/**
* @throws InvalidArgumentException
* @throws Bitrix24PartnerNotFoundException
*/
#[Test]
#[DataProvider('bitrix24PartnerDataProvider')]
#[TestDox('test save with two bitrix24partner number')]
final public function testSaveWithTwoBitrix24PartnerNumber(
Uuid $uuid,
Bitrix24PartnerStatus $bitrix24PartnerStatus,
string $title,
?int $bitrix24PartnerNumber,
?string $site,
?PhoneNumber $phoneNumber,
?string $email,
?string $openLineId,
?string $externalId,
string $comment
): void {
$b24Partner = $this->createBitrix24PartnerImplementation($uuid, $bitrix24PartnerStatus, $title, $bitrix24PartnerNumber, $site, $phoneNumber, $email, $openLineId, $externalId);
$b24PartnerRepository = $this->createBitrix24PartnerRepositoryImplementation();
$flusher = $this->createRepositoryFlusherImplementation();

$b24PartnerRepository->save($b24Partner);
$flusher->flush();

$res = $b24PartnerRepository->getById($b24Partner->getId());
$this->assertEquals($b24Partner, $res);

$secondB24Partner = $this->createBitrix24PartnerImplementation(Uuid::v7(), $bitrix24PartnerStatus, $title, $bitrix24PartnerNumber, $site, $phoneNumber, $email, $openLineId, $externalId);
$this->expectException(InvalidArgumentException::class);
$b24PartnerRepository->save($secondB24Partner);
}

/**
* @throws InvalidArgumentException
* @throws Bitrix24PartnerNotFoundException
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,6 @@ public function findByExternalId(string $externalId, ?Bitrix24PartnerStatus $bit
return $items;
}

/**
* @throws InvalidArgumentException
*/
#[\Override]
public function save(Bitrix24PartnerInterface $bitrix24Partner): void
{
Expand All @@ -119,17 +116,6 @@ public function save(Bitrix24PartnerInterface $bitrix24Partner): void
'bitrix24PartnerNumber' => $bitrix24Partner->getBitrix24PartnerNumber()
]);

$existsPartner = $this->findByBitrix24PartnerNumber($bitrix24Partner->getBitrix24PartnerNumber());
if ($existsPartner instanceof Bitrix24PartnerInterface && $existsPartner->getId() !== $bitrix24Partner->getId()) {
throw new InvalidArgumentException(sprintf(
'bitrix24 partner «%s» with bitrix24 partner number is «%s» already exists with id «%s» in status «%s»',
$existsPartner->getTitle(),
$bitrix24Partner->getBitrix24PartnerNumber(),
$existsPartner->getId(),
$existsPartner->getStatus()->name
));
}

$this->items[$bitrix24Partner->getId()->toRfc4122()] = $bitrix24Partner;
}

Expand Down
Loading