Source of file VersionedResolverTest.php
Size: 8,872 Bytes - Last Modified: 2021-12-23T10:35:47+00:00
/var/www/docs.ssmods.com/process/src/tests/php/GraphQL/Resolvers/VersionedResolverTest.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 | <?php namespace SilverStripe\Versioned\GraphQL\Resolvers; use Exception; use InvalidArgumentException; use SilverStripe\ORM\DataObject; use SilverStripe\Security\Member; use SilverStripe\Dev\SapphireTest; use SilverStripe\Security\Security; use SilverStripe\Versioned\Versioned; use SilverStripe\GraphQL\Schema\Schema; use GraphQL\Type\Definition\ResolveInfo; use SilverStripe\Versioned\Tests\GraphQL\Fake\Fake; use SilverStripe\Versioned\Tests\GraphQL\Fake\FakeResolveInfo; use SilverStripe\Versioned\GraphQL\Resolvers\VersionedResolver; use SilverStripe\Versioned\Tests\GraphQL\Fake\FakeDataObjectStub; use SilverStripe\Versioned\GraphQL\Operations\AbstractPublishOperationCreator; // GraphQL dependency is optional in versioned, // and the following implementation relies on existence of this class (in GraphQL v4) if (!class_exists(Schema::class)) { return; } class VersionedResolverTest extends SapphireTest { protected $usesDatabase = true; public static $extra_dataobjects = [ Fake::class, FakeDataObjectStub::class, ]; protected function setUp(): void { parent::setUp(); if (!class_exists(Schema::class)) { $this->markTestSkipped('Skipped GraphQL 4 test ' . __CLASS__); } } public function testVersionedRead() { /* @var Fake|Versioned $record */ $record = new Fake(); $record->Name = 'First'; $record->write(); $this->logInWithPermission('ADMIN'); $member = Security::getCurrentUser(); $list = Fake::get(); $resolvedList = VersionedResolver::resolveVersionedRead( $list, ['versioning' => [ 'mode' => Versioned::LIVE ]], ['currentUser' => $member], new FakeResolveInfo() ); $this->assertEquals( $resolvedList->Count(), 0, 'Excludes draft records records in live mode' ); $record->publishSingle(); $list = Fake::get(); $resolvedList = VersionedResolver::resolveVersionedRead( $list, ['versioning' => [ 'mode' => Versioned::LIVE ]], ['currentUser' => $member], new FakeResolveInfo() ); $this->assertEquals( $resolvedList->Count(), 1, 'Includes live records records in live mode' ); $this->assertEquals( $resolvedList->First()->ID, $record->ID, 'Includes live records records in live mode' ); } public function testCopyToStage() { /* @var Fake|Versioned $record */ $record = new Fake(); $record->Name = 'First'; $record->write(); // v1 $this->logInWithPermission('ADMIN'); $member = Security::getCurrentUser(); $resolve = VersionedResolver::resolveCopyToStage(['dataClass' => Fake::class]); $resolve( null, [ 'input' => [ 'fromStage' => Versioned::DRAFT, 'toStage' => Versioned::LIVE, 'id' => $record->ID, ], ], [ 'currentUser' => $member ], new FakeResolveInfo() ); $recordLive = Versioned::get_by_stage(Fake::class, Versioned::LIVE) ->byID($record->ID); $this->assertNotNull($recordLive); $this->assertEquals($record->ID, $recordLive->ID); $record->Name = 'Second'; $record->write(); $newVersion = $record->Version; $recordLive = Versioned::get_by_stage(Fake::class, Versioned::LIVE) ->byID($record->ID); $this->assertEquals('First', $recordLive->Title); // Invoke publish $resolve( null, [ 'input' => [ 'fromVersion' => $newVersion, 'toStage' => Versioned::LIVE, 'id' => $record->ID, ], ], [ 'currentUser' => $member ], new FakeResolveInfo() ); $recordLive = Versioned::get_by_stage(Fake::class, Versioned::LIVE) ->byID($record->ID); $this->assertEquals('Second', $recordLive->Title); // Test error $this->expectException(\InvalidArgumentException::class); $resolve( null, [ 'input' => [ 'toStage' => Versioned::DRAFT, 'id' => $record->ID, ], ], [ 'currentUser' => new Member() ], new FakeResolveInfo() ); } public function testPublish() { $record = new Fake(); $record->Name = 'First'; $record->write(); $result = Versioned::get_by_stage(Fake::class, Versioned::LIVE) ->byID($record->ID); $this->assertNull($result); $this->logInWithPermission('ADMIN'); $member = Security::getCurrentUser(); $resolve = VersionedResolver::resolvePublishOperation([ 'dataClass' => Fake::class, 'action' => AbstractPublishOperationCreator::ACTION_PUBLISH ]); $resolve( null, [ 'id' => $record->ID ], [ 'currentUser' => $member ], new FakeResolveInfo() ); $result = Versioned::get_by_stage(Fake::class, Versioned::LIVE) ->byID($record->ID); $this->assertNotNull($result); $this->assertInstanceOf(Fake::class, $result); $this->assertEquals('First', $result->Name); $this->expectException(Exception::class); $this->expectExceptionMessageMatches('/^Not allowed/'); $resolve( null, [ 'id' => $record->ID ], [ 'currentUser' => new Member() ], new FakeResolveInfo() ); } public function testUnpublish() { $record = new Fake(); $record->Name = 'First'; $record->write(); $record->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE); $result = Versioned::get_by_stage(Fake::class, Versioned::LIVE) ->byID($record->ID); $this->assertNotNull($result); $this->assertInstanceOf(Fake::class, $result); $this->assertEquals('First', $result->Name); $this->logInWithPermission('ADMIN'); $member = Security::getCurrentUser(); $doResolve = VersionedResolver::resolvePublishOperation([ 'dataClass' => Fake::class, 'action' => AbstractPublishOperationCreator::ACTION_UNPUBLISH ]); $doResolve( null, [ 'id' => $record->ID ], [ 'currentUser' => $member ], new FakeResolveInfo() ); $result = Versioned::get_by_stage(Fake::class, Versioned::LIVE) ->byID($record->ID); $this->assertNull($result); $record->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE); $this->expectException(Exception::class); $this->expectExceptionMessageMatches('/^Not allowed/'); $doResolve( null, [ 'id' => $record->ID ], [ 'currentUser' => new Member() ], new FakeResolveInfo() ); } public function testRollbackCannotBePerformedWithoutEditPermission() { // Create a fake version of our stub $this->expectException(\InvalidArgumentException::class); $this->expectExceptionMessageMatches('/Current user does not have permission to roll back this resource/'); $stub = FakeDataObjectStub::create(); $stub->Name = 'First'; $stub->Editable = false; $stub->write(); $this->doRollbackMutation($stub); } public function testRollbackRecursiveIsCalled() { // Create a fake version of our stub $stub = FakeDataObjectStub::create(); $stub->Name = 'First'; $stub->write(); $this->doRollbackMutation($stub); $this->assertTrue($stub::$rollbackCalled, 'RollbackRecursive was called'); } protected function doRollbackMutation(DataObject $stub, $toVersion = 1, $member = null) { if (!$stub->isInDB()) { $stub->write(); } $doRollback = VersionedResolver::resolveRollback(['dataClass' => get_class($stub)]); $args = [ 'id' => $stub->ID, 'toVersion' => $toVersion, ]; $doRollback( null, $args, [ 'currentUser' => $member ?: Security::getCurrentUser() ], new FakeResolveInfo() ); } } |