diff --git a/SilMock/Google/Service/Directory/Resource/Groups.php b/SilMock/Google/Service/Directory/Resource/Groups.php index 05a1a91..31dd654 100644 --- a/SilMock/Google/Service/Directory/Resource/Groups.php +++ b/SilMock/Google/Service/Directory/Resource/Groups.php @@ -5,6 +5,7 @@ use Exception; use Google\Service\Directory\Group as GoogleDirectory_Group; use Google\Service\Directory\Groups as GoogleDirectory_Groups; +use Google\Service\Directory\Alias as GoogleDirectory_GroupAlias; use SilMock\Google\Service\DbClass; use SilMock\Google\Service\Directory\ObjectUtils; @@ -20,23 +21,47 @@ public function delete(string $groupKey) $groupRecords = $this->getRecords(); foreach ($groupRecords as $groupRecord) { $groupRecordData = json_decode($groupRecord['data'], true); - if ($groupRecordData['email'] === $groupKey) { + $keysToCheck = $groupRecordData['aliases']; + $keysToCheck[] = $groupRecordData['email']; + if (in_array($groupKey, $keysToCheck)) { $this->deleteRecordById($groupRecord['id']); + $groupAliasesObject = new GroupsAliases($this->dbFile); + $groupAliasesObject->deletedByGroup($groupRecordData['email']); } } } public function get(string $groupKey): ?GoogleDirectory_Group { + $matchingGroupKey = null; + $groupRecords = $this->getRecords(); + foreach ($groupRecords as $groupRecord) { + $groupRecordData = json_decode($groupRecord['data'], true); + $keysToCheck = $groupRecordData['aliases']; + $keysToCheck[] = $groupRecordData['email']; + if (in_array($groupKey, $keysToCheck)) { + $matchingGroupKey = $groupRecordData['email']; + } + } + if ($matchingGroupKey === null) { + return null; + } $mockGroupsObject = new Groups($this->dbFile); $groupsObject = $mockGroupsObject->listGroups(); $groups = $groupsObject->getGroups(); + $matchedGroup = null; foreach ($groups as $group) { - if (mb_strtolower($group->getEmail()) === mb_strtolower($groupKey)) { - return $group; + if (mb_strtolower($group->getEmail()) === mb_strtolower($matchingGroupKey)) { + $matchedGroup = $group; + break; } } - return null; + if ($matchedGroup !== null) { + $mockGroupsAliasesObject = new GroupsAliases($this->dbFile); + $aliases = $mockGroupsAliasesObject->listGroupsAliases($matchedGroup->getEmail()); + $matchedGroup->setAliases($aliases->getAliases()); + } + return $matchedGroup; } /** @@ -49,12 +74,14 @@ public function insert(GoogleDirectory_Group $postBody, $optParams = []) $postBody['id'] = $postBody['id'] ?? $id; $dataAsJson = json_encode(get_object_vars($postBody)); $this->addRecord($dataAsJson); + } else { + throw new Exception( + "Cannot group.insert an existing group: " . $postBody->getEmail() + ); } - $newGroup = new GoogleDirectory_Group(); - ObjectUtils::initialize($newGroup, $postBody); - - return $newGroup; + // This should leave aliases as is. + return $this->get($postBody->getEmail()); } /** @@ -104,4 +131,31 @@ protected function isNewGroup(string $groupKey): bool $uppercaseGroupEmailAddress = mb_strtoupper($groupKey); return ! in_array($uppercaseGroupEmailAddress, $groupEmailAddresses); } + + public function update(string $groupKey, GoogleDirectory_Group $postBody, $optParams = []): GoogleDirectory_Group + { + if ($this->isNewGroup($postBody->getEmail())) { + throw new Exception("Group '{$groupKey}' does not exist."); + } + $group = $this->get($groupKey); + + // remember aliases, because they don't change. + $aliases = $group->getAliases(); + + // update by deleting and reinserting, deletion causes a loss of aliases + $this->delete($groupKey); + ObjectUtils::initialize($group, $postBody); + $this->insert($group); + + // re-add the aliases + $mockGroupAliasesObject = new GroupsAliases($this->dbFile); + foreach ($aliases as $alias) { + $aliasObject = new GoogleDirectory_GroupAlias(); + $aliasObject->setAlias($alias); + $aliasObject->setPrimaryEmail($group->getEmail()); + $mockGroupAliasesObject->insert($groupKey, $aliasObject); + } + + return $this->get($groupKey); + } } diff --git a/SilMock/Google/Service/Directory/Resource/GroupsAliases.php b/SilMock/Google/Service/Directory/Resource/GroupsAliases.php index fbfb9bb..89db123 100644 --- a/SilMock/Google/Service/Directory/Resource/GroupsAliases.php +++ b/SilMock/Google/Service/Directory/Resource/GroupsAliases.php @@ -15,6 +15,16 @@ public function __construct(?string $dbFile = null) parent::__construct($dbFile, 'directory', 'groupsaliases'); } + public function deletedByGroup(string $groupKey): void + { + foreach ($this->getRecords() as $aliasRecord) { + $aliasRecordData = json_decode($aliasRecord['data'], true); + if ($aliasRecordData['primaryEmail'] === $groupKey) { + $this->deleteRecordById($aliasRecord['id']); + } + } + } + public function delete(string $groupKey, string $alias, array $optParams = []) { $groupAliasRecords = $this->getRecords(); diff --git a/SilMock/tests/Google/Service/Directory/Resource/GroupsTest.php b/SilMock/tests/Google/Service/Directory/Resource/GroupsTest.php index 7725979..dece0f1 100644 --- a/SilMock/tests/Google/Service/Directory/Resource/GroupsTest.php +++ b/SilMock/tests/Google/Service/Directory/Resource/GroupsTest.php @@ -4,6 +4,7 @@ use Exception; use Google\Service\Directory\Group as GoogleDirectory_Group; +use Google\Service\Directory\Alias as GoogleDirectory_GroupAlias; use PHPUnit\Framework\TestCase; use SilMock\Google\Service\Directory as GoogleMock_Directory; @@ -13,13 +14,28 @@ class GroupsTest extends TestCase // They are very dependent on order run. // groups.insert, groups.listGroups, members.insert, members.listMembers public string $dataFile = DATAFILE5; - public const GROUP_EMAIL_ADDRESS = 'sample_group@groups.example.com'; + public const GROUP_EMAIL_ADDRESS = 'sample_group@example.com'; + public const GROUP_ALIAS_ADDRESS = 'ma_org_sample_group@groups.example.com'; + + protected function deleteGroupAndAliasesIfTheyExists(string $groupName) + { + $mockGoogleServiceDirectory = new GoogleMock_Directory('anyclient', $this->dataFile); + $group = $mockGoogleServiceDirectory->groups->get($groupName); + if ($group !== null) { + $mockGoogleServiceDirectory->groups->delete($groupName); + } + $group = $mockGoogleServiceDirectory->groups->get($groupName); + self::assertNull($group, "Failed to clean up previous tests."); + } public function testInsert() { + $this->deleteGroupAndAliasesIfTheyExists(self::GROUP_EMAIL_ADDRESS); $group = new GoogleDirectory_Group(); $group->setEmail(self::GROUP_EMAIL_ADDRESS); - $group->setAliases([]); + // See https://developers.google.com/admin-sdk/directory/reference/rest/v1/groups#Group + // setting the aliases will not add, remove, or change aliases at all. + $group->setAliases([self::GROUP_ALIAS_ADDRESS]); $group->setName('Sample Group'); $group->setDescription('A Sample Group used for testing'); @@ -35,14 +51,50 @@ public function testInsert() ); } self::assertTrue($addedGroup instanceof GoogleDirectory_Group); + self::assertEmpty($addedGroup->getAliases(), "Expecting no group aliases inserted by group.insert"); + } + + public function testUpdate() + { + $this->deleteGroupAndAliasesIfTheyExists(self::GROUP_EMAIL_ADDRESS . 'update'); + $group = new GoogleDirectory_Group(); + $group->setEmail(self::GROUP_EMAIL_ADDRESS . 'update'); + // See https://developers.google.com/admin-sdk/directory/reference/rest/v1/groups#Group + // setting the aliases will not add, remove, or change aliases at all. + $group->setAliases([self::GROUP_ALIAS_ADDRESS . 'update']); + $group->setName('Sample Group Update'); + $group->setDescription('A Sample Group used for testing update'); + + $mockGoogleServiceDirectory = new GoogleMock_Directory('anyclient', $this->dataFile); + try { + $addedGroup = $mockGoogleServiceDirectory->groups->insert($group); + } catch (Exception $exception) { + self::fail( + sprintf( + 'Was expecting the groups.insert method to function, but got: %s', + $exception->getMessage() + ) + ); + } + self::assertTrue($addedGroup instanceof GoogleDirectory_Group); + self::assertEmpty($addedGroup->getAliases(), "Expecting no group aliases inserted by group.insert"); + + // See https://developers.google.com/admin-sdk/directory/reference/rest/v1/groups#Group + // setting the aliases will not add, remove, or change aliases at all. + $group->setAliases([self::GROUP_ALIAS_ADDRESS . 'update-change']); + $updatedGroup = $mockGoogleServiceDirectory->groups->update($group->getEmail(), $group); + self::assertTrue($updatedGroup instanceof GoogleDirectory_Group); + self::assertEmpty($updatedGroup->getAliases(), "Expecting no group aliases changed by group.update"); } - public function testDelete() + protected function deleteTestSetup() { // Set update a deletable email address $group = new GoogleDirectory_Group(); $group->setEmail(self::GROUP_EMAIL_ADDRESS . 'delete'); - $group->setAliases([]); + // See https://developers.google.com/admin-sdk/directory/reference/rest/v1/groups#Group + // setting the aliases will not add, remove, or change aliases at all. + $group->setAliases([self::GROUP_ALIAS_ADDRESS . 'delete']); $group->setName('Sample Deletable Group'); $group->setDescription('A Sample Deletable Group used for testing'); @@ -58,6 +110,32 @@ public function testDelete() ); } self::assertTrue($addedGroup instanceof GoogleDirectory_Group); + self::assertEmpty($addedGroup->getAliases(), "Expecting no group aliases"); + + // Set update a deletable email address + $groupAlias = new GoogleDirectory_GroupAlias(); + $groupAlias->setPrimaryEmail(self::GROUP_EMAIL_ADDRESS . 'delete'); + $groupAlias->setAlias(self::GROUP_ALIAS_ADDRESS . 'delete'); + + try { + $addedGroupAliases = $mockGoogleServiceDirectory->groups_aliases->insert( + self::GROUP_EMAIL_ADDRESS . 'delete', + $groupAlias + ); + } catch (Exception $exception) { + self::fail( + sprintf( + 'Was expecting the groups_aliases.insert method to function, but got: %s', + $exception->getMessage() + ) + ); + } + self::assertTrue($addedGroupAliases instanceof GoogleDirectory_GroupAlias); + } + + public function testDeleteByName() + { + $this->deleteTestSetup(); // Now try to delete it $mockGoogleServiceDirectory = new GoogleMock_Directory('anyclient', $this->dataFile); @@ -66,7 +144,7 @@ public function testDelete() } catch (Exception $exception) { self::fail( sprintf( - 'Was expecting the groups.delete method to function, but got: %s', + 'Was expecting the groups.delete method to function for name, but got: %s', $exception->getMessage() ) ); @@ -76,23 +154,95 @@ public function testDelete() $group = $mockGoogleServiceDirectory->groups->get(self::GROUP_EMAIL_ADDRESS . 'delete'); self::assertNull( $group, - 'Was expecting the group to be deleted, but found something' + 'Was expecting the group to be deleted by name, but found something' ); } catch (Exception $exception) { self::fail( sprintf( - 'Was expecting to confirm the group was deleted, but got: %s', + 'Was expecting to confirm the group was deleted by name, but got: %s', + $exception->getMessage() + ) + ); + } + try { + $groupAliases = $mockGoogleServiceDirectory->groups_aliases->listGroupsAliases( + self::GROUP_EMAIL_ADDRESS . 'delete' + ); + self::assertEmpty( + $groupAliases->getAliases(), + 'Was expecting the group aliases to be deleted by name, but found something' + ); + } catch (Exception $exception) { + self::fail( + sprintf( + 'Was expecting to confirm the group aliases were also deleted by name, but got: %s', + $exception->getMessage() + ) + ); + } + } + + public function testDeleteByAlias() + { + $this->deleteTestSetup(); + + // Now try to delete it + $mockGoogleServiceDirectory = new GoogleMock_Directory('anyclient', $this->dataFile); + try { + $mockGoogleServiceDirectory->groups->delete(self::GROUP_ALIAS_ADDRESS . 'delete'); + } catch (Exception $exception) { + self::fail( + sprintf( + 'Was expecting the groups.delete method to function for aliases, but got: %s', + $exception->getMessage() + ) + ); + } + + try { + $group = $mockGoogleServiceDirectory->groups->get(self::GROUP_EMAIL_ADDRESS . 'delete'); + self::assertNull( + $group, + 'Was expecting the group to be deleted by alias, but found something' + ); + } catch (Exception $exception) { + self::fail( + sprintf( + 'Was expecting to confirm the group was deleted by alias, but got: %s', + $exception->getMessage() + ) + ); + } + try { + $groupAliases = $mockGoogleServiceDirectory->groups_aliases->listGroupsAliases(self::GROUP_EMAIL_ADDRESS . 'delete'); + self::assertEmpty( + $groupAliases->getAliases(), + 'Was expecting the group aliases to be deleted by name, but found something' + ); + } catch (Exception $exception) { + self::fail( + sprintf( + 'Was expecting to confirm the group aliases were also deleted by name, but got: %s', $exception->getMessage() ) ); } } - public function testGet() + public function testGetByName() { $mockGoogleServiceDirectory = new GoogleMock_Directory('anyclient', $this->dataFile); $group = $mockGoogleServiceDirectory->groups->get(self::GROUP_EMAIL_ADDRESS); self::assertInstanceOf(GoogleDirectory_Group::class, $group); + self::assertEquals(self::GROUP_EMAIL_ADDRESS, $group->getEmail()); + } + + public function testGetByAlias() + { + $mockGoogleServiceDirectory = new GoogleMock_Directory('anyclient', $this->dataFile); + $group = $mockGoogleServiceDirectory->groups->get(self::GROUP_ALIAS_ADDRESS); + self::assertInstanceOf(GoogleDirectory_Group::class, $group); + self::assertEquals(self::GROUP_EMAIL_ADDRESS, $group->getEmail()); } public function testListGroups() @@ -100,7 +250,7 @@ public function testListGroups() $mockGoogleServiceDirectory = new GoogleMock_Directory('anyclient', $this->dataFile); $groups = []; try { - $groups = $mockGoogleServiceDirectory->groups->listGroups(self::GROUP_EMAIL_ADDRESS); + $groups = $mockGoogleServiceDirectory->groups->listGroups(); } catch (Exception $exception) { self::fail( sprintf( diff --git a/SilMock/tests/Google/Service/Directory/Resource/MembersTest.php b/SilMock/tests/Google/Service/Directory/Resource/MembersTest.php index b14ac41..839a2a6 100644 --- a/SilMock/tests/Google/Service/Directory/Resource/MembersTest.php +++ b/SilMock/tests/Google/Service/Directory/Resource/MembersTest.php @@ -13,11 +13,12 @@ class MembersTest extends TestCase // They are very dependent on order run. // groups.insert, groups.listGroups, members.insert, members.listMembers public string $dataFile = DATAFILE5; + public const MEMBER_EMAIL_ADDRESS = 'member@example.com'; public function testInsert() { - $emailAddress = 'test@example.com'; - $groupEmailAddress = 'sample_group@groups.example.com'; + $emailAddress = self::MEMBER_EMAIL_ADDRESS; + $groupEmailAddress = GroupsTest::GROUP_EMAIL_ADDRESS; $member = new GoogleDirectory_Member(); $member->setEmail($emailAddress); @@ -39,8 +40,8 @@ public function testInsert() public function testGet() { - $groupEmailAddress = 'sample_group@groups.example.com'; - $emailAddress = 'test@example.com'; + $groupEmailAddress = GroupsTest::GROUP_EMAIL_ADDRESS; + $emailAddress = self::MEMBER_EMAIL_ADDRESS; $mockGoogleServiceDirectory = new GoogleMock_Directory('anyclient', $this->dataFile); try { $member = $mockGoogleServiceDirectory->members->get($groupEmailAddress, $emailAddress); @@ -57,12 +58,12 @@ public function testGet() public function testHasMember() { - $groupEmailAddress = 'sample_group@groups.example.com'; + $groupEmailAddress = GroupsTest::GROUP_EMAIL_ADDRESS; $mockGoogleServiceDirectory = new GoogleMock_Directory('anyclient', $this->dataFile); try { $result = $mockGoogleServiceDirectory->members->hasMember( $groupEmailAddress, - 'test@example.com' + self::MEMBER_EMAIL_ADDRESS ); $hasMember = $result['isMember'] ?? false; } catch (Exception $exception) { @@ -75,7 +76,7 @@ public function testHasMember() public function testListMembersAll() { - $groupEmailAddress = 'sample_group@groups.example.com'; + $groupEmailAddress = GroupsTest::GROUP_EMAIL_ADDRESS; $mockGoogleServiceDirectory = new GoogleMock_Directory('anyclient', $this->dataFile); $members = []; try { @@ -91,7 +92,7 @@ public function testListMembersAll() public function testListMembersOnlyMember() { - $groupEmailAddress = 'sample_group@groups.example.com'; + $groupEmailAddress = GroupsTest::GROUP_EMAIL_ADDRESS; $mockGoogleServiceDirectory = new GoogleMock_Directory('anyclient', $this->dataFile); $members = []; try { @@ -112,7 +113,7 @@ public function testListMembersOnlyMember() public function testListMembersOnlyOwner() { - $groupEmailAddress = 'sample_group@groups.example.com'; + $groupEmailAddress = GroupsTest::GROUP_EMAIL_ADDRESS; $mockGoogleServiceDirectory = new GoogleMock_Directory('anyclient', $this->dataFile); $members = []; try { @@ -134,8 +135,8 @@ public function testListMembersOnlyOwner() public function testDelete() { $mockGoogleServiceDirectory = new GoogleMock_Directory('anyclient', $this->dataFile); - $groupEmailAddress = 'sample_group@groups.example.com'; - $emailAddress = 'test@example.com'; + $groupEmailAddress = GroupsTest::GROUP_EMAIL_ADDRESS; + $emailAddress = self::MEMBER_EMAIL_ADDRESS; try { $result = $mockGoogleServiceDirectory->members->hasMember( $groupEmailAddress, @@ -159,7 +160,7 @@ public function testDelete() try { $result = $mockGoogleServiceDirectory->members->hasMember( $groupEmailAddress, - 'test@example.com' + self::MEMBER_EMAIL_ADDRESS ); $hasMember = $result['isMember'] ?? false; } catch (Exception $exception) { diff --git a/composer.json b/composer.json index e7f86eb..9fc069b 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,6 @@ { "name": "silinternational/google-api-php-client-mock", + "version": "2.13.0", "description": "Attempting to create an intelligent mock of the Google API PHP Client for unit and functional testing.", "type": "library", "keywords": [ diff --git a/composer.lock b/composer.lock index 107c53b..0093d28 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7e5c29f633db0a2bd3ea5e0e775e9592", + "content-hash": "08c15db16ea28b2055642d25c855bc2f", "packages": [ { "name": "firebase/php-jwt", - "version": "v6.10.1", + "version": "v6.10.2", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", - "reference": "500501c2ce893c824c801da135d02661199f60c5" + "reference": "30c19ed0f3264cb660ea496895cfb6ef7ee3653b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/500501c2ce893c824c801da135d02661199f60c5", - "reference": "500501c2ce893c824c801da135d02661199f60c5", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/30c19ed0f3264cb660ea496895cfb6ef7ee3653b", + "reference": "30c19ed0f3264cb660ea496895cfb6ef7ee3653b", "shasum": "" }, "require": { @@ -65,9 +65,9 @@ ], "support": { "issues": "https://github.com/firebase/php-jwt/issues", - "source": "https://github.com/firebase/php-jwt/tree/v6.10.1" + "source": "https://github.com/firebase/php-jwt/tree/v6.10.2" }, - "time": "2024-05-18T18:05:11+00:00" + "time": "2024-11-24T11:22:49+00:00" }, { "name": "google/apiclient", @@ -184,16 +184,16 @@ }, { "name": "google/auth", - "version": "v1.43.0", + "version": "v1.44.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-auth-library-php.git", - "reference": "b6a80acd906492086db59aada9196dcfb9c512fe" + "reference": "5670e56307d7a2eac931f677c0e59a4f8abb2e43" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/b6a80acd906492086db59aada9196dcfb9c512fe", - "reference": "b6a80acd906492086db59aada9196dcfb9c512fe", + "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/5670e56307d7a2eac931f677c0e59a4f8abb2e43", + "reference": "5670e56307d7a2eac931f677c0e59a4f8abb2e43", "shasum": "" }, "require": { @@ -238,9 +238,9 @@ "support": { "docs": "https://googleapis.github.io/google-auth-library-php/main/", "issues": "https://github.com/googleapis/google-auth-library-php/issues", - "source": "https://github.com/googleapis/google-auth-library-php/tree/v1.43.0" + "source": "https://github.com/googleapis/google-auth-library-php/tree/v1.44.0" }, - "time": "2024-11-07T19:35:20+00:00" + "time": "2024-12-04T15:34:58+00:00" }, { "name": "guzzlehttp/guzzle", @@ -1201,16 +1201,16 @@ }, { "name": "symfony/deprecation-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", - "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", "shasum": "" }, "require": { @@ -1248,7 +1248,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" }, "funding": [ { @@ -1264,7 +1264,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "webmozart/assert", @@ -1953,16 +1953,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.6.21", + "version": "9.6.22", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "de6abf3b6f8dd955fac3caad3af7a9504e8c2ffa" + "reference": "f80235cb4d3caa59ae09be3adf1ded27521d1a9c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/de6abf3b6f8dd955fac3caad3af7a9504e8c2ffa", - "reference": "de6abf3b6f8dd955fac3caad3af7a9504e8c2ffa", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f80235cb4d3caa59ae09be3adf1ded27521d1a9c", + "reference": "f80235cb4d3caa59ae09be3adf1ded27521d1a9c", "shasum": "" }, "require": { @@ -1973,7 +1973,7 @@ "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.12.0", + "myclabs/deep-copy": "^1.12.1", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", "php": ">=7.3", @@ -2036,7 +2036,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.21" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.22" }, "funding": [ { @@ -2052,7 +2052,7 @@ "type": "tidelift" } ], - "time": "2024-09-19T10:50:18+00:00" + "time": "2024-12-05T13:48:26+00:00" }, { "name": "sebastian/cli-parser", @@ -3124,7 +3124,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { @@ -3133,6 +3133,6 @@ "ext-mbstring": "*", "ext-pdo": "*" }, - "platform-dev": [], + "platform-dev": {}, "plugin-api-version": "2.6.0" }