alias(static function () use ($write): never { self::fail($write . ' ran although Divi is locked'); }); } Functions\when('current_user_can')->justReturn(true); } /** @return iterable}> */ public static function writes(): iterable { $post = new WP_Post(['ID' => 7, 'post_content' => '', 'post_type' => 'page']); $spec = new LibraryItemSpec('Hero', 'section', false, 'regular', null, 'page'); $page = [DiviFeature::PageWrite]; $tb = [DiviFeature::ThemeBuilderWrite]; yield 'save' => [static fn () => (new DiviSaver())->save($post, ''), $page]; yield 'save library item' => [ static fn () => (new DiviSaver())->save($post, 'x', SaveScope::LibraryItem), [DiviFeature::PageWrite, DiviFeature::LibraryWrite], ]; yield 'save global item' => [ static fn () => (new DiviSaver())->save($post, 'x', SaveScope::GlobalItem), [DiviFeature::PageWrite, DiviFeature::LibraryWrite], ]; yield 'save tb layout' => [ static fn () => (new DiviSaver())->save($post, 'x', SaveScope::ThemeBuilderLayout), [DiviFeature::PageWrite, DiviFeature::ThemeBuilderWrite], ]; yield 'saveNew' => [static fn () => (new DiviSaver())->saveNew(7, ''), $page]; yield 'saveNew library item' => [ static fn () => (new DiviSaver())->saveNew(7, 'x', SaveScope::LibraryItem), [DiviFeature::PageWrite, DiviFeature::LibraryWrite], ]; yield 'pages setFlags' => [static fn () => DiviPages::setFlags(7), $page]; yield 'library create' => [static fn () => (new DiviLibraryStore())->create( $spec, new NewDraft(null, FakeChangeLog::forbidden(), 'lit/library-save', 'et_pb_layout', 'Bibliothekseintrag') ), [DiviFeature::LibraryWrite]]; yield 'tb liveId create' => [static fn () => (new DiviThemeBuilder())->liveId(true), $tb]; yield 'tb insertLayout' => [static fn () => (new DiviThemeBuilder())->insertLayout('header', 'Kopf'), $tb]; yield 'tb storeTemplate' => [static fn () => (new DiviThemeBuilder())->storeTemplate(3, [ 'title' => 'V', 'layouts' => [], 'use_on' => [], 'exclude_from' => [], ]), $tb]; yield 'tb attach' => [static fn () => (new DiviThemeBuilder())->attach(3, 9), $tb]; yield 'tb detach' => [static fn () => (new DiviThemeBuilder())->detach(3, 9), $tb]; yield 'tb setConditions' => [static fn () => (new DiviThemeBuilder())->setConditions(9, ['singular'], []), $tb]; yield 'tb setEnabled' => [static fn () => (new DiviThemeBuilder())->setEnabled(9, true), $tb]; yield 'tb unmarkUnused' => [static fn () => (new DiviThemeBuilder())->unmarkUnused(9), $tb]; yield 'design savePresets' => [ static fn () => (new DesignSystemWriter())->savePresets(['module' => [], 'group' => []], false), [DiviFeature::PresetWrite], ]; } /** * @dataProvider writes * @param list $needs */ public function testRefusesBeforeTheFirstWriteWhenAFeatureItNeedsIsLocked(callable $write, array $needs): void { foreach ([ReleaseState::Untested, ReleaseState::Incompatible] as $state) { foreach ($needs as $feature) { ReleaseGate::useResolver(static fn (): ReleaseStatus => ReleaseMatrices::status([$feature], $state)); try { $write(); self::fail(sprintf('%s %s must refuse', $feature->value, $state->value)); } catch (DiviLocked $locked) { self::assertSame([$feature], $locked->features); } } } } /** * @dataProvider writes * @param list $needs */ public function testPassesTheGateWhenOnlyOtherFeaturesAreLocked(callable $write, array $needs): void { $others = array_values(array_filter( DiviFeature::cases(), static fn (DiviFeature $feature): bool => ! in_array($feature, $needs, true) )); ReleaseGate::useResolver( static fn (): ReleaseStatus => ReleaseMatrices::status($others, ReleaseState::Incompatible) ); // Past the gate the method may write or fail on the missing Divi – anything but the lock. foreach (self::WRITES as $name) { Functions\when($name)->alias(static function () use ($name): never { throw new RuntimeException($name . ' reached'); }); } try { $write(); } catch (DiviLocked $locked) { self::fail('refused although only other features are locked: ' . $locked->getMessage()); } catch (Throwable) { // Reached the code behind the gate. } self::addToAssertionCount(1); } public function testTheCheckPageMayBeWrittenWhileProbing(): void { ReleaseGate::useResolver( static fn (): ReleaseStatus => ReleaseMatrices::uniform(ReleaseState::Untested, '5.3.0') ); Functions\when('wp_update_post')->justReturn(41); Functions\when('update_post_meta')->justReturn(true); Functions\when('get_post_meta')->alias( static fn (int $id, string $key): string => $key === '_et_pb_show_page_creation' ? 'off' : 'on' ); Functions\when('get_post')->justReturn(new WP_Post(['ID' => 41, 'post_content' => 'x'])); Functions\when('has_filter')->justReturn(false); $warnings = ReleaseGate::whileProbing(41, static fn () => (new DiviSaver())->saveNew(41, 'x')); self::assertSame([], $warnings); } }