Source of file CloudflarePurgeTest.php
Size: 26,543 Bytes - Last Modified: 2021-12-23T10:07:25+00:00
/var/www/docs.ssmods.com/process/src/tests/CloudflarePurgeTest.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758 | <?php namespace NSWDPC\Utilities\Cloudflare\Tests; use NSWDPC\Utilities\Cloudflare\DataObjectPurgeable; use NSWDPC\Utilities\Cloudflare\CloudflarePurgeService; use NSWDPC\Utilities\Cloudflare\Logger; use NSWDPC\Utilities\Cloudflare\PurgeRecord; use NSWDPC\Utilities\Cloudflare\URLCachePurgeJob; use NSWDPC\Utilities\Cloudflare\HostCachePurgeJob; use NSWDPC\Utilities\Cloudflare\EntireCachePurgeJob; use NSWDPC\Utilities\Cloudflare\PrefixCachePurgeJob; use NSWDPC\Utilities\Cloudflare\TagCachePurgeJob; use SilverStripe\Core\Injector\Injector; use SilverStripe\ORM\DataObject; use SilverStripe\Dev\TestOnly; use SilverStripe\Dev\SapphireTest; use SilverStripe\Versioned\Versioned; use Symbiote\Cloudflare\Cloudflare; use Symbiote\QueuedJobs\DataObjects\QueuedJobDescriptor; use Symbiote\QueuedJobs\Services\QueuedJobService; /** * Test functionality provided by the module * Note: requires a service to accept HTTP requests * @author James */ class CloudflarePurgeTest extends SapphireTest { protected $usesDatabase = true; protected $client; protected static $extra_dataobjects = [ TestVersionedRecord::class, PurgeRecord::class ]; protected static $required_extensions = [ TestVersionedRecord::class => [ Versioned::class, DataObjectPurgeable::class ], PurgeRecord::class => [ Versioned::class, DataObjectPurgeable::class ] ]; public function setUp() { parent::setUp(); // Mock a CloudflarePurgeService Injector::inst()->load([ Cloudflare::class => [ 'class' => MockCloudflarePurgeService::class, ] ]); $this->client = Injector::inst()->get( Cloudflare::class ); $this->assertTrue($this->client instanceof MockCloudflarePurgeService, "Client is not a MockCloudflarePurgeService"); QueuedJobService::config()->set('use_shutdown_function', false); } /** * @return QueuedJobService */ protected function getQueuedJobService() { return singleton(QueuedJobService::class); } public function testPurgeRecordURL() { $purge = PurgeRecord::create([ 'Title' => 'Purge URLs', 'Type' => CloudflarePurgeService::TYPE_URL, 'TypeValues' => [ 'https://example.com', '/foo/bar' ] ]); $purge->write(); $purge->doPublish(); $values = $purge->TypeValues; // test that a job was created for this record $descriptors = $purge->getCurrentPurgeJobDescriptors( [ URLCachePurgeJob::class ] ); $this->assertEquals(1, $descriptors->count(), "Jobs count should be 1"); $descriptor = $descriptors->first(); $job_data = unserialize($descriptor->SavedJobData); $this->assertEquals(DataObjectPurgeable::REASON_PUBLISH, $job_data->reason); $job = Injector::inst()->createWithArgs( $descriptor->Implementation, [ DataObjectPurgeable::REASON_PUBLISH, $purge ] ); $job->setup(); $job->process(); // check data $data = $this->client->getAdapter()->getData(); $headers = $this->client->getAdapter()->getHeaders(); $client_headers = $this->client->getAdapter()->getClientHeaders(); $uri = $this->client->getAdapter()->getLastUri(); $this->assertTrue(isset($data['files']), "'files' does not exist in POST data"); $keys = array_keys($data); $this->assertEquals(1, count($keys), "There should only be one key in the data, found: " . count($data)); $values = $purge->getPurgeTypeValues( $purge->Type ); $this->assertEquals($values, $data['files'], "Purged files sent in data does not match record getPurgeTypeValues"); $this->assertEquals("zones/{$this->client->getZoneIdentifier()}/purge_cache", $uri, "URI mismatch"); $this->assertEquals( [ $this->client->config()->get('email'), $this->client->config()->get('auth_key') ], array_values($client_headers), "Client AUTH headers mismatch" ); $purge->doUnpublish(); // test that a job was created for this record reason = 'write' $descriptors = $purge->getCurrentPurgeJobDescriptors( [ URLCachePurgeJob::class ] ); $this->assertEquals(1, $descriptors->count(), "Jobs count should be 1"); $descriptor = $descriptors->first(); $job_data = unserialize($descriptor->SavedJobData); $this->assertEquals(DataObjectPurgeable::REASON_UNPUBLISH, $job_data->reason); $job = Injector::inst()->createWithArgs( $descriptor->Implementation, [ DataObjectPurgeable::REASON_UNPUBLISH, $purge ] ); $job->setup(); $job->process(); // check data $data = $this->client->getAdapter()->getData(); $headers = $this->client->getAdapter()->getHeaders(); $client_headers = $this->client->getAdapter()->getClientHeaders(); $uri = $this->client->getAdapter()->getLastUri(); $this->assertTrue(isset($data['files']), "'files' does not exist in POST data"); $keys = array_keys($data); $this->assertEquals(1, count($keys), "There should only be one key in the data, found: " . count($data)); $values = $purge->getPurgeTypeValues( $purge->Type ); $this->assertEquals($values, $data['files'], "Purged files sent in data does not match record getPurgeTypeValues"); $this->assertEquals("zones/{$this->client->getZoneIdentifier()}/purge_cache", $uri, "URI mismatch"); $this->assertEquals( [ $this->client->config()->get('email'), $this->client->config()->get('auth_key') ], array_values($client_headers), "Client AUTH headers mismatch" ); $purge->delete(); $descriptors = $purge->getCurrentPurgeJobDescriptors( [ URLCachePurgeJob::class ] ); $this->assertEquals(0, $descriptors->count(), "Jobs count should be 0 after delete"); } private function createAndPublish() { $record = TestVersionedRecord::create([ 'Title' => 'Test record write' ]); // test values are sane $types = $record->getPurgeTypes(); $this->assertEquals(1, count($types), "getPurgeTypes count is not 1"); $this->assertEquals(CloudflarePurgeService::TYPE_URL, $types[0], "type is not CloudflarePurgeService::TYPE_URL"); $urls = $record->getPurgeUrlList(); $this->assertEquals(2, count($urls), "getPurgeUrlList count is not 2"); $this->assertTrue(array_search($record->AbsoluteLink(), $urls) !== false, "AbsoluteLink not found in getPurgeUrlList"); $this->assertTrue(array_search($record->SomeRelatedLink(), $urls) !== false, "SomeRelatedLink not found in getPurgeUrlList"); $record->write(); $record->doPublish(); // test that a job was created for this record $descriptors = $record->getCurrentPurgeJobDescriptors( [ URLCachePurgeJob::class ] ); $this->assertEquals(1, $descriptors->count(), "Jobs count should be 1"); $descriptor = $descriptors->first(); $job_data = unserialize($descriptor->SavedJobData); $this->assertEquals(DataObjectPurgeable::REASON_PUBLISH, $job_data->reason); $job = Injector::inst()->createWithArgs( $descriptor->Implementation, [ DataObjectPurgeable::REASON_PUBLISH, $record ] ); $job->setup(); $job->process(); // check data $data = $this->client->getAdapter()->getData(); $headers = $this->client->getAdapter()->getHeaders(); $client_headers = $this->client->getAdapter()->getClientHeaders(); $uri = $this->client->getAdapter()->getLastUri(); $this->assertTrue(isset($data['files']), "'files' does not exist in POST data"); $keys = array_keys($data); $this->assertEquals(1, count($keys), "There should only be one key in the data, found: " . count($data)); $this->assertEquals($record->getPurgeUrlList(), $data['files'], "Purged files sent in data does not match record getPurgeUrlList"); $this->assertEquals("zones/{$this->client->getZoneIdentifier()}/purge_cache", $uri, "URI mismatch"); $this->assertEquals( [ $this->client->config()->get('email'), $this->client->config()->get('auth_key') ], array_values($client_headers), "Client AUTH headers mismatch" ); return $record; } public function testRecordPublish() { $this->createAndPublish(); } public function testRecordUnpublish() { $record = $this->createAndPublish(); $record->doUnPublish(); // test that a job was created for this record reason = 'write' $descriptors = $record->getCurrentPurgeJobDescriptors( [ URLCachePurgeJob::class ] ); $this->assertEquals(1, $descriptors->count(), "Jobs count should be 1"); $descriptor = $descriptors->first(); $job_data = unserialize($descriptor->SavedJobData); $this->assertEquals(DataObjectPurgeable::REASON_UNPUBLISH, $job_data->reason); $job = Injector::inst()->createWithArgs( $descriptor->Implementation, [ DataObjectPurgeable::REASON_UNPUBLISH, $record ] ); $job->setup(); $job->process(); // check data $data = $this->client->getAdapter()->getData(); $headers = $this->client->getAdapter()->getHeaders(); $client_headers = $this->client->getAdapter()->getClientHeaders(); $uri = $this->client->getAdapter()->getLastUri(); $this->assertTrue(isset($data['files']), "'files' does not exist in POST data"); $keys = array_keys($data); $this->assertEquals(1, count($keys), "There should only be one key in the data, found: " . count($data)); $this->assertEquals($record->getPurgeUrlList(), $data['files'], "Purged files sent in data does not match record getPurgeUrlList"); $this->assertEquals("zones/{$this->client->getZoneIdentifier()}/purge_cache", $uri, "URI mismatch"); $this->assertEquals( [ $this->client->config()->get('email'), $this->client->config()->get('auth_key') ], array_values($client_headers), "Client AUTH headers mismatch" ); $record->delete(); $descriptors = $record->getCurrentPurgeJobDescriptors( [ URLCachePurgeJob::class ] ); $this->assertEquals(0, $descriptors->count(), "Jobs count should be 0 after delete"); } public function testPurgeRecordHost() { $hosts = [ 'www.example.com', 'images.example.com' ]; $purge = PurgeRecord::create([ 'Title' => 'Purge HOST', 'Type' => CloudflarePurgeService::TYPE_HOST, 'TypeValues' => $hosts ]); $purge->write(); $purge->doPublish(); $values = $purge->getPurgeTypeValues($purge->Type); $this->assertEquals(count($hosts), count($values), "Host count mismatch"); // test that a job was created for this record $descriptors = $purge->getCurrentPurgeJobDescriptors( [ HostCachePurgeJob::class ] ); $this->assertEquals(1, $descriptors->count(), "Jobs count should be 1"); $descriptor = $descriptors->first(); $job_data = unserialize($descriptor->SavedJobData); $this->assertEquals(DataObjectPurgeable::REASON_PUBLISH, $job_data->reason); $job = Injector::inst()->createWithArgs( $descriptor->Implementation, [ DataObjectPurgeable::REASON_PUBLISH, $purge ] ); $job->setup(); $job->process(); // check data $data = $this->client->getAdapter()->getData(); $headers = $this->client->getAdapter()->getHeaders(); $client_headers = $this->client->getAdapter()->getClientHeaders(); $uri = $this->client->getAdapter()->getLastUri(); $this->assertTrue(isset($data['hosts']), "'hosts' does not exist in POST data"); $keys = array_keys($data); $this->assertEquals(1, count($keys), "There should only be one key in the data, found: " . count($data)); $values = $purge->getPurgeTypeValues( $purge->Type ); $this->assertEquals($values, $data['hosts'], "Purged hosts sent in data does not match record getPurgeTypeValues"); $this->assertEquals("zones/{$this->client->getZoneIdentifier()}/purge_cache", $uri, "URI mismatch"); $this->assertEquals( [ $this->client->config()->get('email'), $this->client->config()->get('auth_key') ], array_values($client_headers), "Client AUTH headers mismatch" ); $purge->doUnpublish(); // test that a job was created for this record reason = 'write' $descriptors = $purge->getCurrentPurgeJobDescriptors( [ HostCachePurgeJob::class ] ); $this->assertEquals(1, $descriptors->count(), "Jobs count should be 1"); $descriptor = $descriptors->first(); $job_data = unserialize($descriptor->SavedJobData); $this->assertEquals(DataObjectPurgeable::REASON_UNPUBLISH, $job_data->reason); $job = Injector::inst()->createWithArgs( $descriptor->Implementation, [ DataObjectPurgeable::REASON_UNPUBLISH, $purge ] ); $job->setup(); $job->process(); // check data $data = $this->client->getAdapter()->getData(); $headers = $this->client->getAdapter()->getHeaders(); $client_headers = $this->client->getAdapter()->getClientHeaders(); $uri = $this->client->getAdapter()->getLastUri(); $this->assertTrue(isset($data['hosts']), "'hosts' does not exist in POST data"); $keys = array_keys($data); $this->assertEquals(1, count($keys), "There should only be one key in the data, found: " . count($data)); $values = $purge->getPurgeTypeValues( $purge->Type ); $this->assertEquals($values, $data['hosts'], "Purged hosts sent in data does not match record getPurgeTypeValues"); $this->assertEquals("zones/{$this->client->getZoneIdentifier()}/purge_cache", $uri, "URI mismatch"); $this->assertEquals( [ $this->client->config()->get('email'), $this->client->config()->get('auth_key') ], array_values($client_headers), "Client AUTH headers mismatch" ); $purge->delete(); $descriptors = $purge->getCurrentPurgeJobDescriptors( [ HostCachePurgeJob::class ] ); $this->assertEquals(0, $descriptors->count(), "Jobs count should be 0 after delete"); } public function testPurgeRecordPrefix() { $prefixes = [ 'www.example.com/foo', 'images.example.com/bar' ]; $purge = PurgeRecord::create([ 'Title' => 'Purge PREFIX', 'Type' => CloudflarePurgeService::TYPE_PREFIX, 'TypeValues' => $prefixes ]); $purge->write(); $purge->doPublish(); $values = $purge->getPurgeTypeValues($purge->Type); $this->assertEquals(count($prefixes), count($values), "Prefix count mismatch"); // test that a job was created for this record $descriptors = $purge->getCurrentPurgeJobDescriptors( [ PrefixCachePurgeJob::class ] ); $this->assertEquals(1, $descriptors->count(), "Jobs count should be 1"); $descriptor = $descriptors->first(); $job_data = unserialize($descriptor->SavedJobData); $this->assertEquals(DataObjectPurgeable::REASON_PUBLISH, $job_data->reason); $job = Injector::inst()->createWithArgs( $descriptor->Implementation, [ DataObjectPurgeable::REASON_PUBLISH, $purge ] ); $job->setup(); $job->process(); // check data $data = $this->client->getAdapter()->getData(); $headers = $this->client->getAdapter()->getHeaders(); $client_headers = $this->client->getAdapter()->getClientHeaders(); $uri = $this->client->getAdapter()->getLastUri(); $this->assertTrue(isset($data['prefixes']), "'prefixes' does not exist in POST data"); $keys = array_keys($data); $this->assertEquals(1, count($keys), "There should only be one key in the data, found: " . count($data)); $values = $purge->getPurgeTypeValues( $purge->Type ); $this->assertEquals($values, $data['prefixes'], "Purged prefixes sent in data does not match record getPurgeTypeValues"); $this->assertEquals("zones/{$this->client->getZoneIdentifier()}/purge_cache", $uri, "URI mismatch"); $this->assertEquals( [ $this->client->config()->get('email'), $this->client->config()->get('auth_key') ], array_values($client_headers), "Client AUTH headers mismatch" ); $purge->doUnpublish(); // test that a job was created for this record reason = 'write' $descriptors = $purge->getCurrentPurgeJobDescriptors( [ PrefixCachePurgeJob::class ] ); $this->assertEquals(1, $descriptors->count(), "Jobs count should be 1"); $descriptor = $descriptors->first(); $job_data = unserialize($descriptor->SavedJobData); $this->assertEquals(DataObjectPurgeable::REASON_UNPUBLISH, $job_data->reason); $job = Injector::inst()->createWithArgs( $descriptor->Implementation, [ DataObjectPurgeable::REASON_UNPUBLISH, $purge ] ); $job->setup(); $job->process(); // check data $data = $this->client->getAdapter()->getData(); $headers = $this->client->getAdapter()->getHeaders(); $client_headers = $this->client->getAdapter()->getClientHeaders(); $uri = $this->client->getAdapter()->getLastUri(); $this->assertTrue(isset($data['prefixes']), "'prefixes' does not exist in POST data"); $keys = array_keys($data); $this->assertEquals(1, count($keys), "There should only be one key in the data, found: " . count($data)); $values = $purge->getPurgeTypeValues( $purge->Type ); $this->assertEquals($values, $data['prefixes'], "Purged prefixes sent in data does not match record getPurgeTypeValues"); $this->assertEquals("zones/{$this->client->getZoneIdentifier()}/purge_cache", $uri, "URI mismatch"); $this->assertEquals( [ $this->client->config()->get('email'), $this->client->config()->get('auth_key') ], array_values($client_headers), "Client AUTH headers mismatch" ); $purge->delete(); $descriptors = $purge->getCurrentPurgeJobDescriptors( [ PrefixCachePurgeJob::class ] ); $this->assertEquals(0, $descriptors->count(), "Jobs count should be 0 after delete"); } public function testPurgeRecordTag() { $tags= [ 'foo', 'bar', 'tag-three' ]; $purge = PurgeRecord::create([ 'Title' => 'Purge TAG', 'Type' => CloudflarePurgeService::TYPE_TAG, 'TypeValues' => $tags ]); $purge->write(); $purge->doPublish(); $values = $purge->getPurgeTypeValues($purge->Type); $this->assertEquals(count($tags), count($values), "Prefix count mismatch"); // test that a job was created for this record $descriptors = $purge->getCurrentPurgeJobDescriptors( [ TagCachePurgeJob::class ] ); $this->assertEquals(1, $descriptors->count(), "Jobs count should be 1"); $descriptor = $descriptors->first(); $job_data = unserialize($descriptor->SavedJobData); $this->assertEquals(DataObjectPurgeable::REASON_PUBLISH, $job_data->reason); $job = Injector::inst()->createWithArgs( $descriptor->Implementation, [ DataObjectPurgeable::REASON_PUBLISH, $purge ] ); $job->setup(); $job->process(); // check data $data = $this->client->getAdapter()->getData(); $headers = $this->client->getAdapter()->getHeaders(); $client_headers = $this->client->getAdapter()->getClientHeaders(); $uri = $this->client->getAdapter()->getLastUri(); $this->assertTrue(isset($data['tags']), "'tags' does not exist in POST data"); $keys = array_keys($data); $this->assertEquals(1, count($keys), "There should only be one key in the data, found: " . count($data)); $values = $purge->getPurgeTypeValues( $purge->Type ); $this->assertEquals($values, $data['tags'], "Purged tags sent in data does not match record getPurgeTypeValues"); $this->assertEquals("zones/{$this->client->getZoneIdentifier()}/purge_cache", $uri, "URI mismatch"); $this->assertEquals( [ $this->client->config()->get('email'), $this->client->config()->get('auth_key') ], array_values($client_headers), "Client AUTH headers mismatch" ); $purge->doUnpublish(); // test that a job was created for this record reason = 'write' $descriptors = $purge->getCurrentPurgeJobDescriptors( [ TagCachePurgeJob::class ] ); $this->assertEquals(1, $descriptors->count(), "Jobs count should be 1"); $descriptor = $descriptors->first(); $job_data = unserialize($descriptor->SavedJobData); $this->assertEquals(DataObjectPurgeable::REASON_UNPUBLISH, $job_data->reason); $job = Injector::inst()->createWithArgs( $descriptor->Implementation, [ DataObjectPurgeable::REASON_UNPUBLISH, $purge ] ); $job->setup(); $job->process(); // check data $data = $this->client->getAdapter()->getData(); $headers = $this->client->getAdapter()->getHeaders(); $client_headers = $this->client->getAdapter()->getClientHeaders(); $uri = $this->client->getAdapter()->getLastUri(); $this->assertTrue(isset($data['tags']), "'tags' does not exist in POST data"); $keys = array_keys($data); $this->assertEquals(1, count($keys), "There should only be one key in the data, found: " . count($data)); $values = $purge->getPurgeTypeValues( $purge->Type ); $this->assertEquals($values, $data['tags'], "Purged tags sent in data does not match record getPurgeTypeValues"); $this->assertEquals("zones/{$this->client->getZoneIdentifier()}/purge_cache", $uri, "URI mismatch"); $this->assertEquals( [ $this->client->config()->get('email'), $this->client->config()->get('auth_key') ], array_values($client_headers), "Client AUTH headers mismatch" ); $purge->delete(); $descriptors = $purge->getCurrentPurgeJobDescriptors( [ TagCachePurgeJob::class ] ); $this->assertEquals(0, $descriptors->count(), "Jobs count should be 0 after delete"); } public function testPurgeAll() { $result = $this->client->purgeAll(); $this->assertNotEquals(false, $result, "purgeAll returned false"); $descriptors = QueuedJobDescriptor::get()->filter(['Implementation' => EntireCachePurgeJob::class]); $this->assertEquals(1, $descriptors->count(), "Jobs count should be 1"); $job = Injector::inst()->create(EntireCachePurgeJob::class); $job->setUp(); $job->process(); // check data $data = $this->client->getAdapter()->getData(); $headers = $this->client->getAdapter()->getHeaders(); $client_headers = $this->client->getAdapter()->getClientHeaders(); $uri = $this->client->getAdapter()->getLastUri(); $this->assertTrue(isset($data['purge_everything']), "'purge_everything' does not exist in POST data"); $keys = array_keys($data); $this->assertEquals(1, count($keys), "There should only be one key in the data, found: " . count($data)); $this->assertEquals( [ $this->client->config()->get('email'), $this->client->config()->get('auth_key') ], array_values($client_headers), "Client AUTH headers mismatch" ); $this->assertEquals("zones/{$this->client->getZoneIdentifier()}/purge_cache", $uri, "URI mismatch"); } } class TestVersionedRecord extends DataObject implements TestOnly { private static $db = [ 'Title' => 'Varchar(255)' ]; private static $table_name = "TestVersionedRecord"; private static $extensions = [ Versioned::class, DataObjectPurgeable::class ]; public function AbsoluteLink() { return "https://example.com/testversionedrecord.html"; } public function SomeRelatedLink() { return "https://example.com/testversionedrecord.html?alternateformat=1"; } public function getPurgeUrlList() { return [ $this->AbsoluteLink(), $this->SomeRelatedLink() ]; } /** * This record has a URL that is support */ public function getPurgeTypes() : array { return [ CloudflarePurgeService::TYPE_URL ]; } } |