From ee5822dc831d09ac12520e9b2a6f95c91569935a Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Thu, 16 May 2024 13:44:14 +0200 Subject: [PATCH] PHPStan for tests --- composer.json | 10 +- inc/CLI/InfoCommand.php | 2 +- inc/Configuration.php | 20 +-- inc/Export.php | 8 +- inc/Loader/Base.php | 2 +- inc/Project.php | 2 +- inc/ProjectLocator.php | 6 +- inc/Repository/Base.php | 4 +- inc/Runner.php | 4 +- inc/Updater.php | 4 +- inc/WebhookHandler/Base.php | 8 +- inc/WebhookHandler/Bitbucket.php | 2 +- inc/WebhookHandler/GitHub.php | 4 +- inc/WebhookHandlerFactory.php | 3 +- inc/ZipProvider.php | 7 +- phpcs.xml.dist | 5 +- phpstan.neon.dist | 4 +- tests/phpstan/stubs/factory.php | 129 ++++++++++++++++++ tests/phpstan/stubs/test-stubs.php | 13 ++ tests/phpstan/stubs/testcase-route.php | 55 ++++++++ tests/phpstan/stubs/testcase.php | 68 +++++++++ tests/phpunit/tests/Behat/FeatureContext.php | 18 +-- tests/phpunit/tests/Configuration.php | 1 + tests/phpunit/tests/Export.php | 84 +++++++----- tests/phpunit/tests/Loader/Git.php | 8 +- tests/phpunit/tests/Loader/Mercurial.php | 8 +- tests/phpunit/tests/Loader/Subversion.php | 8 +- tests/phpunit/tests/LoaderFactory.php | 8 +- tests/phpunit/tests/Project.php | 4 +- tests/phpunit/tests/ProjectLocator.php | 19 ++- tests/phpunit/tests/Repository/Bitbucket.php | 6 +- tests/phpunit/tests/Repository/GitHub.php | 8 +- tests/phpunit/tests/Repository/GitLab.php | 6 +- tests/phpunit/tests/RepositoryFactory.php | 20 +-- tests/phpunit/tests/Runner.php | 2 +- tests/phpunit/tests/TestCase.php | 15 ++ tests/phpunit/tests/TranslationApiRoute.php | 79 ++++++++--- tests/phpunit/tests/Updater.php | 2 +- .../tests/WebhookHandler/Bitbucket.php | 25 ++-- tests/phpunit/tests/WebhookHandler/GitHub.php | 30 ++-- tests/phpunit/tests/WebhookHandler/GitLab.php | 2 +- .../tests/WebhookHandler/LegacyGitHub.php | 29 ++-- tests/phpunit/tests/ZipProvider.php | 66 +++++---- 43 files changed, 590 insertions(+), 218 deletions(-) create mode 100644 tests/phpstan/stubs/factory.php create mode 100644 tests/phpstan/stubs/test-stubs.php create mode 100644 tests/phpstan/stubs/testcase-route.php create mode 100644 tests/phpstan/stubs/testcase.php diff --git a/composer.json b/composer.json index 5de988c7..fff916ea 100644 --- a/composer.json +++ b/composer.json @@ -41,16 +41,18 @@ "wearerequired/traduttore-registry": "^2.0" }, "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^v1.0.0", - "php-stubs/wp-cli-stubs": "^v2.10", + "dealerdirect/phpcodesniffer-composer-installer": "^1.0.0", + "php-stubs/wordpress-tests-stubs": "^6.5", + "php-stubs/wp-cli-stubs": "^2.10", "phpstan/extension-installer": "^1.3", "phpstan/phpstan-deprecation-rules": "^1.2", + "phpstan/phpstan-phpunit": "^1.4", "swissspidy/phpstan-no-private": "^0.2.0", "szepeviktor/phpstan-wordpress": "^1.3", "wearerequired/coding-standards": "^6.0", "wp-cli/extension-command": "^2.0", "wp-cli/rewrite-command": "^2.0", - "wp-cli/wp-cli-tests": "^v4.2.9", + "wp-cli/wp-cli-tests": "^4.2.9", "wpackagist-plugin/glotpress": "^4.0.0", "yoast/phpunit-polyfills": "^1.1" }, @@ -75,8 +77,8 @@ }, "config": { "allow-plugins": { - "dealerdirect/phpcodesniffer-composer-installer": true, "composer/installers": true, + "dealerdirect/phpcodesniffer-composer-installer": true, "phpstan/extension-installer": true }, "process-timeout": 7200, diff --git a/inc/CLI/InfoCommand.php b/inc/CLI/InfoCommand.php index e04e42c7..bd9fd769 100644 --- a/inc/CLI/InfoCommand.php +++ b/inc/CLI/InfoCommand.php @@ -149,7 +149,7 @@ protected function get_svn_binary_path(): ?string { * @return null|string Binary path on success, null otherwise. */ protected function get_wp_binary_path(): ?string { - if ( \defined( 'TRADUTTORE_WP_BIN' ) && TRADUTTORE_WP_BIN ) { + if ( \defined( 'TRADUTTORE_WP_BIN' ) && is_string( TRADUTTORE_WP_BIN ) ) { return TRADUTTORE_WP_BIN; } diff --git a/inc/Configuration.php b/inc/Configuration.php index b2cb857f..3885e38b 100644 --- a/inc/Configuration.php +++ b/inc/Configuration.php @@ -22,16 +22,16 @@ class Configuration { * * @var string Repository path. */ - protected $path; + protected string $path; /** * Repository configuration. * * @since 3.0.0 * - * @phpstan-var ProjectConfig - * * @var array Repository configuration. + * + * @phpstan-var ProjectConfig */ protected $config = []; @@ -64,9 +64,9 @@ public function get_path(): string { * * @since 3.0.0 * - * @phpstan-return ProjectConfig - * * @return array Repository configuration. + * + * @phpstan-return ProjectConfig */ public function get_config(): array { return $this->config; @@ -77,12 +77,12 @@ public function get_config(): array { * * @since 3.0.0 * + * @param string $key Config key. + * @return string|string[]|null Config value. + * * @phpstan-template T of key-of * @phpstan-param T $key * @phpstan-return ProjectConfig[T] | null - * - * @param string $key Config key. - * @return string|string[]|null Config value. */ public function get_config_value( string $key ) { if ( isset( $this->config[ $key ] ) ) { @@ -97,9 +97,9 @@ public function get_config_value( string $key ) { * * @since 3.0.0 * - * @phpstan-return ProjectConfig - * * @return array Configuration data if found. + * + * @phpstan-return ProjectConfig */ protected function load_config(): array { $config_file = trailingslashit( $this->path ) . 'traduttore.json'; diff --git a/inc/Export.php b/inc/Export.php index 45ef7c73..f3bd0e94 100644 --- a/inc/Export.php +++ b/inc/Export.php @@ -25,7 +25,7 @@ class Export { * * @var \GP_Translation_Set */ - protected $translation_set; + protected GP_Translation_Set $translation_set; /** * The current locale. @@ -43,7 +43,7 @@ class Export { * * @var \Required\Traduttore\Project */ - protected $project; + protected Project $project; /** * List of generated files. @@ -52,12 +52,14 @@ class Export { * * @var string[] */ - protected $files; + protected array $files; /** * Export constructor. * * @param \GP_Translation_Set $translation_set The translation set this export is for. + * + * @throws \InvalidArgumentException */ public function __construct( GP_Translation_Set $translation_set ) { $this->translation_set = $translation_set; diff --git a/inc/Loader/Base.php b/inc/Loader/Base.php index a5fe8a74..b9f7bf61 100644 --- a/inc/Loader/Base.php +++ b/inc/Loader/Base.php @@ -21,7 +21,7 @@ abstract class Base implements Loader { * * @var \Required\Traduttore\Repository Repository object. */ - protected $repository; + protected Repository $repository; /** * Class constructor. diff --git a/inc/Project.php b/inc/Project.php index 2ee33b37..cbdb5c96 100644 --- a/inc/Project.php +++ b/inc/Project.php @@ -101,7 +101,7 @@ class Project { * * @var \GP_Project Project information. */ - protected $project; + protected GP_Project $project; /** * Project constructor. diff --git a/inc/ProjectLocator.php b/inc/ProjectLocator.php index 556def8a..05416576 100644 --- a/inc/ProjectLocator.php +++ b/inc/ProjectLocator.php @@ -23,14 +23,14 @@ class ProjectLocator { * * @var \Required\Traduttore\Project|null Project instance. */ - protected $project; + protected ?Project $project; /** * ProjectLocator constructor. * * @since 2.0.0 * - * @param int|string|Project|GP_Project $project Possible GlotPress project ID or path or source code repository path. + * @param int|string|false|\Required\Traduttore\Project|\GP_Project $project Possible GlotPress project ID or path or source code repository path. */ public function __construct( $project ) { $this->project = $this->find_project( $project ); @@ -52,7 +52,7 @@ public function get_project(): ?Project { * * @since 2.0.0 * - * @param int|string|Project|GP_Project $project Possible GlotPress project ID or path or source code repository path. + * @param int|string|false|\Required\Traduttore\Project|\GP_Project $project Possible GlotPress project ID or path or source code repository path. * @return \Required\Traduttore\Project Project instance. */ protected function find_project( $project ): ?Project { diff --git a/inc/Repository/Base.php b/inc/Repository/Base.php index 082e721b..661ae561 100644 --- a/inc/Repository/Base.php +++ b/inc/Repository/Base.php @@ -23,7 +23,7 @@ abstract class Base implements Repository { * * @var \Required\Traduttore\Project Project information. */ - protected $project; + protected Project $project; /** * Loader constructor. @@ -106,7 +106,7 @@ public function get_name(): string { } if ( $url ) { - $path = wp_parse_url( $url, PHP_URL_PATH ); + $path = wp_parse_url( $url, PHP_URL_PATH ); $path = $path ? trim( $path, '/' ) : ''; $parts = explode( '/', $path ); $name = implode( '/', array_splice( $parts, 0, 2 ) ); diff --git a/inc/Runner.php b/inc/Runner.php index d9a65fcf..9e5ff096 100644 --- a/inc/Runner.php +++ b/inc/Runner.php @@ -22,7 +22,7 @@ class Runner { * * @var \Required\Traduttore\Loader VCS loader. */ - protected $loader; + protected Loader $loader; /** * Updater instance. @@ -31,7 +31,7 @@ class Runner { * * @var \Required\Traduttore\Updater Translation updater. */ - protected $updater; + protected Updater $updater; /** * Runner constructor. diff --git a/inc/Updater.php b/inc/Updater.php index 8eb00ffb..7a8ee58a 100644 --- a/inc/Updater.php +++ b/inc/Updater.php @@ -32,7 +32,7 @@ class Updater { * * @var \Required\Traduttore\Project Project information. */ - protected $project; + protected Project $project; /** * Returns a new loader instance for a given project. @@ -221,7 +221,7 @@ protected function create_pot_file( Configuration $config ): ?string { * @return string WP-CLI binary path. */ protected function get_wp_bin(): string { - if ( \defined( 'TRADUTTORE_WP_BIN' ) && TRADUTTORE_WP_BIN ) { + if ( \defined( 'TRADUTTORE_WP_BIN' ) && is_string( TRADUTTORE_WP_BIN ) ) { return TRADUTTORE_WP_BIN; } diff --git a/inc/WebhookHandler/Base.php b/inc/WebhookHandler/Base.php index b36cb5e5..f59f3398 100644 --- a/inc/WebhookHandler/Base.php +++ b/inc/WebhookHandler/Base.php @@ -26,16 +26,16 @@ abstract class Base implements WebhookHandler { * * @phpstan-var \WP_REST_Request */ - protected $request; + protected WP_REST_Request $request; /** * Class constructor. * * @since 3.0.0 * - * @phpstan-param \WP_REST_Request $request - * * @param \WP_REST_Request $request Request object. + * + * @phpstan-param \WP_REST_Request $request */ public function __construct( WP_REST_Request $request ) { $this->request = $request; @@ -79,7 +79,7 @@ protected function get_secret( ?Project $project = null ): ?string { * * @since 3.0.0 * - * @param string $secret Webhook sync secret. + * @param string|null $secret Webhook sync secret. * @param \Required\Traduttore\WebhookHandler $handler The current webhook handler instance. * @param \Required\Traduttore\Project|null $project The current project if passed through. */ diff --git a/inc/WebhookHandler/Bitbucket.php b/inc/WebhookHandler/Bitbucket.php index d200cb15..9b08eeb8 100644 --- a/inc/WebhookHandler/Bitbucket.php +++ b/inc/WebhookHandler/Bitbucket.php @@ -34,7 +34,7 @@ public function permission_callback(): ?bool { return false; } - $token = $this->request->get_header( 'x-hub-signature' ); + $token = $this->request->get_header( 'x-hub-signature-256' ); $params = $this->request->get_params(); $locator = new ProjectLocator( $params['repository']['links']['html']['href'] ?? null ); $project = $locator->get_project(); diff --git a/inc/WebhookHandler/GitHub.php b/inc/WebhookHandler/GitHub.php index 6fa41384..5bded277 100644 --- a/inc/WebhookHandler/GitHub.php +++ b/inc/WebhookHandler/GitHub.php @@ -38,7 +38,7 @@ public function permission_callback(): ?bool { return false; } - $token = $this->request->get_header( 'x-hub-signature' ); + $token = $this->request->get_header( 'x-hub-signature-256' ); if ( ! $token ) { return false; @@ -54,7 +54,7 @@ public function permission_callback(): ?bool { return false; } - $payload_signature = 'sha1=' . hash_hmac( 'sha1', $this->request->get_body(), $secret ); + $payload_signature = 'sha256=' . hash_hmac( 'sha256', $this->request->get_body(), $secret ); return hash_equals( $token, $payload_signature ); } diff --git a/inc/WebhookHandlerFactory.php b/inc/WebhookHandlerFactory.php index d83485b6..0fef946d 100644 --- a/inc/WebhookHandlerFactory.php +++ b/inc/WebhookHandlerFactory.php @@ -23,10 +23,11 @@ class WebhookHandlerFactory { * * @since 3.0.0 * - * @phpstan-param \WP_REST_Request $request * * @param \WP_REST_Request $request Request object. * @return \Required\Traduttore\WebhookHandler Webhook handler instance. + * + * @phpstan-param \WP_REST_Request $request */ public function get_handler( WP_REST_Request $request ): ?WebhookHandler { $handler = null; diff --git a/inc/ZipProvider.php b/inc/ZipProvider.php index 7c3fb28a..87ac2140 100644 --- a/inc/ZipProvider.php +++ b/inc/ZipProvider.php @@ -10,6 +10,7 @@ use DateTime; use DateTimeZone; use GP; +use GP_Locale; use GP_Locales; use GP_Translation_Set; use InvalidArgumentException; @@ -42,7 +43,7 @@ class ZipProvider { * * @var \GP_Translation_Set The translation set. */ - protected $translation_set; + protected GP_Translation_Set $translation_set; /** * The current GlotPress locale. @@ -51,7 +52,7 @@ class ZipProvider { * * @var \GP_Locale The locale. */ - protected $locale; + protected GP_Locale $locale; /** * The current project. @@ -60,7 +61,7 @@ class ZipProvider { * * @var \Required\Traduttore\Project The project. */ - protected $project; + protected Project $project; /** * ZipProvider constructor. diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 2e624dc3..136b6c9c 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -3,7 +3,10 @@ Coding Standard for Traduttore . - /tests/* + /tests/behat/* + /tests/features/* + /tests/phpstan/* + /tests/phpunit/data/* diff --git a/phpstan.neon.dist b/phpstan.neon.dist index ed04ac15..5d481b71 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -7,9 +7,11 @@ parameters: - vendor/wordpress-plugin/glotpress/gp-includes/routes/_main.php scanFiles: - vendor/php-stubs/wp-cli-stubs/wp-cli-stubs.php + - vendor/php-stubs/wordpress-tests-stubs/wordpress-tests-stubs.php scanDirectories: + - tests/phpstan/stubs/ - vendor/wordpress-plugin/glotpress/gp-includes/ - vendor/wordpress-plugin/glotpress/locales/ paths: - inc/ -# - test/ + - tests/phpunit diff --git a/tests/phpstan/stubs/factory.php b/tests/phpstan/stubs/factory.php new file mode 100644 index 00000000..1df2cd3e --- /dev/null +++ b/tests/phpstan/stubs/factory.php @@ -0,0 +1,129 @@ +factory = new GP_UnitTest_Factory(); + + global $wp_rewrite; + if ( GP_TESTS_PERMALINK_STRUCTURE != $wp_rewrite->permalink_structure ) { + $this->set_permalink_structure( GP_TESTS_PERMALINK_STRUCTURE ); + } + } + + /** + * Utility method that resets permalinks and flushes rewrites. + * + * Also updates the pre_option filter for `permalink_structure`. + * + * @global WP_Rewrite $wp_rewrite + * + * @param string $structure Optional. Permalink structure to set. Default empty. + */ + public function set_permalink_structure( $structure = '' ) { + global $wp_tests_options; + + $wp_tests_options['permalink_structure'] = $structure; + + parent::set_permalink_structure( $structure ); + } + + function clean_up_global_scope() { + parent::clean_up_global_scope(); + + $locales = &GP_Locales::instance(); + $locales->locales = array(); + $_GET = array(); + $_POST = array(); + /** + * @todo re-initialize all thing objects + */ + GP::$translation_set = new GP_Translation_Set; + GP::$original = new GP_Original; + } + + function set_normal_user_as_current() { + $user = $this->factory->user->create(); + wp_set_current_user( $user ); + return $user; + } + + function set_admin_user_as_current() { + $admin = $this->factory->user->create_admin(); + wp_set_current_user( $admin ); + return $admin; + } +} diff --git a/tests/phpunit/tests/Behat/FeatureContext.php b/tests/phpunit/tests/Behat/FeatureContext.php index 33db1ca8..821302d2 100644 --- a/tests/phpunit/tests/Behat/FeatureContext.php +++ b/tests/phpunit/tests/Behat/FeatureContext.php @@ -85,7 +85,7 @@ public function given_a_wp_installation_with_the_traduttore_plugin(): void { /** * @Given /^GlotPress (.*) being active$/ */ - public function given_the_glotpress_plugin_being_active( $gp_version ): void { + public function given_the_glotpress_plugin_being_active( string $gp_version ): void { $branch_name = $gp_version; if ( 'nightly' === $gp_version || 'develop' === $gp_version || 'trunk' === $gp_version ) { $branch_name = 'develop'; @@ -120,7 +120,7 @@ public function given_the_glotpress_plugin_being_active( $gp_version ): void { /** * @When /^I (run|try) the WP-CLI command `([^`]+)`$/ */ - public function when_i_run_the_wp_cli_command( $mode, $command ): void { + public function when_i_run_the_wp_cli_command( string $mode, string $command ): void { $command = "wp {$command}"; $with_code_coverage = getenv( 'BEHAT_CODE_COVERAGE' ); @@ -135,8 +135,8 @@ public function when_i_run_the_wp_cli_command( $mode, $command ): void { $command, [ 'BEHAT_PROJECT_DIR' => $this->variables['PROJECT_DIR'], - 'BEHAT_FEATURE_TITLE' => self::$feature->getTitle(), - 'BEHAT_SCENARIO_TITLE' => $this->scenario->getTitle(), + 'BEHAT_FEATURE_TITLE' => self::$feature ? self::$feature->getTitle() : null, + 'BEHAT_SCENARIO_TITLE' => $this->scenario ? $this->scenario->getTitle() : null, ] ), $mode @@ -150,7 +150,7 @@ public function when_i_run_the_wp_cli_command( $mode, $command ): void { * * @param string $directory Directory to ensure the existence of. */ - private function ensure_dir_exists( $directory ): void { + private function ensure_dir_exists( string $directory ): void { $parent = dirname( $directory ); if ( ! empty( $parent ) && ! is_dir( $parent ) ) { @@ -165,11 +165,11 @@ private function ensure_dir_exists( $directory ): void { /** * Create a new process with added environment variables. * - * @param string $command Command to run. - * @param array $env Associative array of environment variables to add. + * @param string $command Command to run. + * @param array $env Associative array of environment variables to add. * @return \WP_CLI\Process Process to execute. */ - public function proc_with_env( $command, $env = [] ): Process { + public function proc_with_env( string $command, array $env = [] ): Process { $env = array_merge( self::get_process_env_variables(), $env @@ -192,6 +192,8 @@ public function proc_with_env( $command, $env = [] ): Process { * Get the environment variables required for launched `wp` processes. * * This is copied over from WP_CLI\Tests\Context\FeatureContext, to enable an adaption of FeatureContext::proc(). + * + * @return array */ private static function get_process_env_variables(): array { // Ensure we're using the expected `wp` binary. diff --git a/tests/phpunit/tests/Configuration.php b/tests/phpunit/tests/Configuration.php index 35d51f34..5d73206c 100644 --- a/tests/phpunit/tests/Configuration.php +++ b/tests/phpunit/tests/Configuration.php @@ -28,6 +28,7 @@ public function test_get_config_empty_directory(): void { public function test_get_config_value_empty_directory(): void { $config = new Config( dirname( __DIR__ ) . '/data/example-no-config' ); + // @phpstan-ignore-next-line $this->assertNull( $config->get_config_value( 'foo' ) ); } diff --git a/tests/phpunit/tests/Export.php b/tests/phpunit/tests/Export.php index d5af5e44..c721ee55 100644 --- a/tests/phpunit/tests/Export.php +++ b/tests/phpunit/tests/Export.php @@ -10,6 +10,7 @@ use GP_Translation_Set; use PO; use \Required\Traduttore\Export as E; +use Translation_Entry; /** * Test cases for \Required\Traduttore\Export. @@ -23,7 +24,7 @@ class Export extends TestCase { public function setUp(): void { parent::setUp(); - $locale = $this->factory->locale->create( + $locale = $this->factory()->locale->create( [ 'english_name' => 'German', 'native_name' => 'Deutsch', @@ -32,7 +33,7 @@ public function setUp(): void { ] ); - $this->translation_set = $this->factory->translation_set->create_with_project( + $this->translation_set = $this->factory()->translation_set->create_with_project( [ 'locale' => $locale->slug, ], @@ -49,14 +50,14 @@ public function test_does_nothing_for_empty_translation_set(): void { } public function test_creates_only_po_and_mo_files(): void { - $original = $this->factory->original->create( + $original = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id, 'references' => 'my-plugin.php', ] ); - $this->factory->translation->create( + $this->factory()->translation->create( [ 'original_id' => $original->id, 'translation_set_id' => $this->translation_set->id, @@ -68,6 +69,8 @@ public function test_creates_only_po_and_mo_files(): void { $actual = $export->export_strings(); + $this->assertIsArray( $actual ); + array_map( 'unlink', $actual ); $this->assertEqualSets( @@ -85,7 +88,7 @@ public function test_creates_multiple_json_files(): void { $filename_2 = 'my-super-minified-script'; /* @var \GP_Original $original_1 */ - $original_1 = $this->factory->original->create( + $original_1 = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id, 'references' => $filename_1 . '.js', @@ -93,14 +96,14 @@ public function test_creates_multiple_json_files(): void { ); /* @var \GP_Original $original_2 */ - $original_2 = $this->factory->original->create( + $original_2 = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id, 'references' => $filename_2 . '.min.js', ] ); - $this->factory->translation->create( + $this->factory()->translation->create( [ 'original_id' => $original_1->id, 'translation_set_id' => $this->translation_set->id, @@ -108,7 +111,7 @@ public function test_creates_multiple_json_files(): void { ] ); - $this->factory->translation->create( + $this->factory()->translation->create( [ 'original_id' => $original_2->id, 'translation_set_id' => $this->translation_set->id, @@ -120,6 +123,8 @@ public function test_creates_multiple_json_files(): void { $actual = $export->export_strings(); + $this->assertIsArray( $actual ); + $json_filename_1 = 'foo-project-de_DE-' . md5( $filename_1 . '.js' ) . '.json'; $json_filename_2 = 'foo-project-de_DE-' . md5( $filename_2 . '.js' ) . '.json'; @@ -128,6 +133,8 @@ public function test_creates_multiple_json_files(): void { array_map( 'unlink', $actual ); + $this->assertIsString( $json_1 ); + $this->assertIsString( $json_2 ); $this->assertJson( $json_1 ); $this->assertJson( $json_2 ); $this->assertEqualSets( @@ -145,9 +152,9 @@ public function test_creates_multiple_json_files(): void { /** * Modify the mapping of sources to translation entries. * - * @param array $mapping The mapping of sources to translation entries. + * @param array $mapping The mapping of sources to translation entries. * - * @return array The maybe modified mapping. + * @return array The maybe modified mapping. */ public function filter_map_entries_to_source( array $mapping ): array { $mapping['build.js'] = array_merge( $mapping['my-super-script.js'], $mapping['my-other-script.js'] ); @@ -163,7 +170,7 @@ public function test_map_entries_to_source_filter(): void { $filename_target = 'build.js'; /* @var \GP_Original $original_1 */ - $original_1 = $this->factory->original->create( + $original_1 = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id, 'references' => $filename_1, @@ -171,14 +178,14 @@ public function test_map_entries_to_source_filter(): void { ); /* @var \GP_Original $original_2 */ - $original_2 = $this->factory->original->create( + $original_2 = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id, 'references' => $filename_2, ] ); - $this->factory->translation->create( + $this->factory()->translation->create( [ 'original_id' => $original_1->id, 'translation_set_id' => $this->translation_set->id, @@ -186,7 +193,7 @@ public function test_map_entries_to_source_filter(): void { ] ); - $this->factory->translation->create( + $this->factory()->translation->create( [ 'original_id' => $original_2->id, 'translation_set_id' => $this->translation_set->id, @@ -200,6 +207,8 @@ public function test_map_entries_to_source_filter(): void { $actual = $export->export_strings(); + $this->assertIsArray( $actual ); + remove_filter( 'traduttore.map_entries_to_source', [ $this, 'filter_map_entries_to_source' ] ); $json_filename_1 = 'foo-project-de_DE-' . md5( $filename_1 ) . '.json'; @@ -213,6 +222,7 @@ public function test_map_entries_to_source_filter(): void { array_map( 'unlink', $actual ); + $this->assertIsString( $json ); $this->assertJson( $json ); $this->assertEqualSets( [ @@ -230,7 +240,7 @@ public function test_js_entries_are_not_in_po_file(): void { $filename_2 = 'my-super-minified-script'; /* @var \GP_Original $original_1 */ - $original_1 = $this->factory->original->create( + $original_1 = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id, 'references' => $filename_1 . '.js', @@ -238,7 +248,7 @@ public function test_js_entries_are_not_in_po_file(): void { ); /* @var \GP_Original $original_2 */ - $original_2 = $this->factory->original->create( + $original_2 = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id, 'references' => $filename_2 . '.min.js', @@ -246,28 +256,28 @@ public function test_js_entries_are_not_in_po_file(): void { ); /* @var \GP_Original $original_3 */ - $original_3 = $this->factory->original->create( + $original_3 = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id, 'references' => 'foo.php', ] ); - $this->factory->translation->create( + $this->factory()->translation->create( [ 'original_id' => $original_1->id, 'translation_set_id' => $this->translation_set->id, 'status' => 'current', ] ); - $this->factory->translation->create( + $this->factory()->translation->create( [ 'original_id' => $original_2->id, 'translation_set_id' => $this->translation_set->id, 'status' => 'current', ] ); - $this->factory->translation->create( + $this->factory()->translation->create( [ 'original_id' => $original_3->id, 'translation_set_id' => $this->translation_set->id, @@ -279,14 +289,19 @@ public function test_js_entries_are_not_in_po_file(): void { $actual = $export->export_strings(); + $this->assertIsArray( $actual ); + $translations = new PO(); $translations->import_from_file( $actual['foo-project-de_DE.po'] ); $json_filename_1 = 'foo-project-de_DE-' . md5( $filename_1 . '.js' ) . '.json'; $json_filename_2 = 'foo-project-de_DE-' . md5( $filename_2 . '.js' ) . '.json'; - $json_1 = json_decode( file_get_contents( $actual[ $json_filename_1 ] ), true ); - $json_2 = json_decode( file_get_contents( $actual[ $json_filename_2 ] ), true ); + $json_1 = json_decode( (string) file_get_contents( $actual[ $json_filename_1 ] ), true ); + $json_2 = json_decode( (string) file_get_contents( $actual[ $json_filename_2 ] ), true ); + + $this->assertIsArray( $json_1 ); + $this->assertIsArray( $json_2 ); array_map( 'unlink', $actual ); @@ -304,7 +319,7 @@ public function test_js_source_entries_are_not_exported_as_json_files(): void { $filename_3 = 'dist/build.js'; /* @var \GP_Original $original_1 */ - $original_1 = $this->factory->original->create( + $original_1 = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id, 'references' => "$filename_1 $filename_3", @@ -312,7 +327,7 @@ public function test_js_source_entries_are_not_exported_as_json_files(): void { ); /* @var \GP_Original $original_2 */ - $original_2 = $this->factory->original->create( + $original_2 = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id, 'references' => "$filename_2 $filename_3", @@ -320,28 +335,28 @@ public function test_js_source_entries_are_not_exported_as_json_files(): void { ); /* @var \GP_Original $original_3 */ - $original_3 = $this->factory->original->create( + $original_3 = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id, 'references' => $filename_3, ] ); - $this->factory->translation->create( + $this->factory()->translation->create( [ 'original_id' => $original_1->id, 'translation_set_id' => $this->translation_set->id, 'status' => 'current', ] ); - $this->factory->translation->create( + $this->factory()->translation->create( [ 'original_id' => $original_2->id, 'translation_set_id' => $this->translation_set->id, 'status' => 'current', ] ); - $this->factory->translation->create( + $this->factory()->translation->create( [ 'original_id' => $original_3->id, 'translation_set_id' => $this->translation_set->id, @@ -353,9 +368,11 @@ public function test_js_source_entries_are_not_exported_as_json_files(): void { $actual = $export->export_strings(); + $this->assertIsArray( $actual ); + $json_filename = 'foo-project-de_DE-' . md5( $filename_3 ) . '.json'; - $json = json_decode( file_get_contents( $actual[ $json_filename ] ), true ); + $json = json_decode( (string) file_get_contents( $actual[ $json_filename ] ), true ); array_map( 'unlink', $actual ); @@ -379,14 +396,14 @@ public function test_json_files_include_file_reference_comment(): void { $filename_1 = 'my-super-script'; /* @var \GP_Original $original_1 */ - $original_1 = $this->factory->original->create( + $original_1 = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id, 'references' => $filename_1 . '.js', ] ); - $this->factory->translation->create( + $this->factory()->translation->create( [ 'original_id' => $original_1->id, 'translation_set_id' => $this->translation_set->id, @@ -398,15 +415,18 @@ public function test_json_files_include_file_reference_comment(): void { $actual = $export->export_strings(); + $this->assertIsArray( $actual ); + $json_filename_1 = 'foo-project-de_DE-' . md5( $filename_1 . '.js' ) . '.json'; $json_1 = file_get_contents( $actual[ $json_filename_1 ] ); array_map( 'unlink', $actual ); + $this->assertIsString( $json_1 ); $this->assertJson( $json_1 ); - $json1_encoded = json_decode( $json_1 ); + $json1_encoded = (object) json_decode( $json_1 ); $this->assertSame( $filename_1 . '.js', $json1_encoded->comment->reference ); } } diff --git a/tests/phpunit/tests/Loader/Git.php b/tests/phpunit/tests/Loader/Git.php index b5fa1662..5baaad13 100644 --- a/tests/phpunit/tests/Loader/Git.php +++ b/tests/phpunit/tests/Loader/Git.php @@ -27,7 +27,7 @@ public function setUp(): void { parent::setUp(); $this->project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Sample Project', 'slug' => 'sample-project', @@ -44,8 +44,9 @@ public function test_get_local_path(): void { } public function test_download_repository(): void { - $this->markTestSkipped( 'Need to mock shell command execution' ); + $this->markTestIncomplete( 'Need to mock shell command execution' ); + // @phpstan-ignore-next-line $loader = new GitLoader( new GitHub( $this->project ) ); add_filter( 'traduttore.git_clone_use_https', '__return_true' ); @@ -56,8 +57,9 @@ public function test_download_repository(): void { } public function test_download_existing_repository(): void { - $this->markTestSkipped( 'Need to mock shell command execution' ); + $this->markTestIncomplete( 'Need to mock shell command execution' ); + // @phpstan-ignore-next-line $loader = new GitLoader( new GitHub( $this->project ) ); add_filter( 'traduttore.git_clone_use_https', '__return_true' ); diff --git a/tests/phpunit/tests/Loader/Mercurial.php b/tests/phpunit/tests/Loader/Mercurial.php index 5694f791..ba3375dc 100644 --- a/tests/phpunit/tests/Loader/Mercurial.php +++ b/tests/phpunit/tests/Loader/Mercurial.php @@ -27,7 +27,7 @@ public function setUp(): void { parent::setUp(); $this->project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Sample Project', 'slug' => 'sample-project', @@ -44,8 +44,9 @@ public function test_get_local_path(): void { } public function test_download_repository(): void { - $this->markTestSkipped( 'Need to mock shell command execution' ); + $this->markTestIncomplete( 'Need to mock shell command execution' ); + // @phpstan-ignore-next-line $loader = new MercurialLoader( new Bitbucket( $this->project ) ); add_filter( 'traduttore.hg_clone_use_https', '__return_true' ); @@ -56,8 +57,9 @@ public function test_download_repository(): void { } public function test_download_existing_repository(): void { - $this->markTestSkipped( 'Need to mock shell command execution' ); + $this->markTestIncomplete( 'Need to mock shell command execution' ); + // @phpstan-ignore-next-line $loader = new MercurialLoader( new Bitbucket( $this->project ) ); add_filter( 'traduttore.hg_clone_use_https', '__return_true' ); diff --git a/tests/phpunit/tests/Loader/Subversion.php b/tests/phpunit/tests/Loader/Subversion.php index 6213f1b3..10058d1d 100644 --- a/tests/phpunit/tests/Loader/Subversion.php +++ b/tests/phpunit/tests/Loader/Subversion.php @@ -27,7 +27,7 @@ public function setUp(): void { parent::setUp(); $this->project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Sample Project', 'slug' => 'sample-project', @@ -44,8 +44,9 @@ public function test_get_local_path(): void { } public function test_download_repository(): void { - $this->markTestSkipped( 'Need to mock shell command execution' ); + $this->markTestIncomplete( 'Need to mock shell command execution' ); + // @phpstan-ignore-next-line $loader = new SubversionLoader( new Bitbucket( $this->project ) ); add_filter( 'traduttore.svn_checkout_use_https', '__return_true' ); @@ -56,8 +57,9 @@ public function test_download_repository(): void { } public function test_download_existing_repository(): void { - $this->markTestSkipped( 'Need to mock shell command execution' ); + $this->markTestIncomplete( 'Need to mock shell command execution' ); + // @phpstan-ignore-next-line $loader = new SubversionLoader( new Bitbucket( $this->project ) ); add_filter( 'traduttore.svn_checkout_use_https', '__return_true' ); diff --git a/tests/phpunit/tests/LoaderFactory.php b/tests/phpunit/tests/LoaderFactory.php index 938d9a4d..5a35920e 100644 --- a/tests/phpunit/tests/LoaderFactory.php +++ b/tests/phpunit/tests/LoaderFactory.php @@ -22,7 +22,7 @@ class LoaderFactory extends TestCase { public function test_get_mercurial_loader(): void { $factory = new Factory(); $project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Project', ] @@ -39,7 +39,7 @@ public function test_get_mercurial_loader(): void { public function test_get_git_loader_for_bitbucket_repository(): void { $factory = new Factory(); $project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Project', ] @@ -54,7 +54,7 @@ public function test_get_git_loader_for_bitbucket_repository(): void { public function test_get_git_loader_for_github_repository(): void { $factory = new Factory(); $project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Project', ] @@ -69,7 +69,7 @@ public function test_get_git_loader_for_github_repository(): void { public function test_get_git_loader_for_gitlab_repository(): void { $factory = new Factory(); $project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Project', ] diff --git a/tests/phpunit/tests/Project.php b/tests/phpunit/tests/Project.php index dfbbe78e..d1e6da6d 100644 --- a/tests/phpunit/tests/Project.php +++ b/tests/phpunit/tests/Project.php @@ -28,7 +28,7 @@ class Project extends TestCase { public function setUp(): void { parent::setUp(); - $this->gp_project = $this->factory->project->create( + $this->gp_project = $this->factory()->project->create( [ 'name' => 'Project', 'active' => 1, @@ -159,7 +159,7 @@ public function test_get_last_updated_time(): void { $this->project->set_last_updated_time( $time ); $this->assertInstanceOf( DateTime::class, $this->project->get_last_updated_time() ); - $this->assertSame( $time->getTimestamp(), $this->project->get_last_updated_time()->getTimestamp(), 'Last updated time is not identical', 1 ); + $this->assertSame( $time->getTimestamp(), $this->project->get_last_updated_time()->getTimestamp(), 'Last updated time is not identical' ); } public function test_get_repository_webhook_secret(): void { diff --git a/tests/phpunit/tests/ProjectLocator.php b/tests/phpunit/tests/ProjectLocator.php index b58c3201..bd19bc9c 100644 --- a/tests/phpunit/tests/ProjectLocator.php +++ b/tests/phpunit/tests/ProjectLocator.php @@ -32,18 +32,18 @@ class ProjectLocator extends TestCase { public function setUp(): void { parent::setUp(); - $this->root = $this->factory->project->create( + $this->root = $this->factory()->project->create( [ 'name' => 'Root', ] ); - $this->sub = $this->factory->project->create( + $this->sub = $this->factory()->project->create( [ 'name' => 'Sub', 'parent_project_id' => $this->root->id, ] ); - $this->subsub = $this->factory->project->create( + $this->subsub = $this->factory()->project->create( [ 'name' => 'SubSub', 'parent_project_id' => $this->sub->id, @@ -81,48 +81,55 @@ public function test_existing_glotpress_project_instance(): void { $project = $this->root; $locator = new Locator( $project ); + $this->assertInstanceOf( Project::class, $locator->get_project() ); $this->assertSame( $this->root->id, $locator->get_project()->get_id() ); } public function test_find_project_by_glotpress_path(): void { $locator = new Locator( 'root' ); + $this->assertInstanceOf( Project::class, $locator->get_project() ); $this->assertSame( $this->root->id, $locator->get_project()->get_id() ); } public function test_find_project_by_glotpress_subpath(): void { $locator = new Locator( 'root/sub' ); + $this->assertInstanceOf( Project::class, $locator->get_project() ); $this->assertSame( $this->sub->id, $locator->get_project()->get_id() ); } public function test_find_project_by_glotpress_subsubpath(): void { $locator = new Locator( 'root/sub/subsub' ); + $this->assertInstanceOf( Project::class, $locator->get_project() ); $this->assertSame( $this->subsub->id, $locator->get_project()->get_id() ); } public function test_find_project_by_glotpress_id(): void { $locator = new Locator( (int) $this->sub->id ); + $this->assertInstanceOf( Project::class, $locator->get_project() ); $this->assertSame( $this->sub->id, $locator->get_project()->get_id() ); } public function test_find_project_by_glotpress_id_as_string(): void { $locator = new Locator( (string) $this->sub->id ); + $this->assertInstanceOf( Project::class, $locator->get_project() ); $this->assertSame( $this->sub->id, $locator->get_project()->get_id() ); } public function test_find_project_by_github_url(): void { $locator = new Locator( 'https://github.com/wearerequired/traduttore' ); + $this->assertInstanceOf( Project::class, $locator->get_project() ); $this->assertSame( $this->subsub->id, $locator->get_project()->get_id() ); } public function test_find_project_by_repository_name(): void { $project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Foo Bar', ] @@ -133,12 +140,13 @@ public function test_find_project_by_repository_name(): void { $locator = new Locator( 'wearerequired/traduttore-registry' ); + $this->assertInstanceOf( Project::class, $locator->get_project() ); $this->assertSame( $project->get_id(), $locator->get_project()->get_id() ); } public function test_find_project_by_repository_url(): void { $project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Foo Bar', ] @@ -149,6 +157,7 @@ public function test_find_project_by_repository_url(): void { $locator = new Locator( 'https://github.com/wearerequired/traduttore-registry' ); + $this->assertInstanceOf( Project::class, $locator->get_project() ); $this->assertSame( $project->get_id(), $locator->get_project()->get_id() ); } } diff --git a/tests/phpunit/tests/Repository/Bitbucket.php b/tests/phpunit/tests/Repository/Bitbucket.php index a3243351..eb40deac 100644 --- a/tests/phpunit/tests/Repository/Bitbucket.php +++ b/tests/phpunit/tests/Repository/Bitbucket.php @@ -30,7 +30,7 @@ public function setUp(): void { parent::setUp(); $this->project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Project', ] @@ -54,7 +54,7 @@ public function test_get_name_falls_back_to_project_slug(): void { public function test_get_name_falls_back_to_source_url_template(): void { $project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Project', 'source_url_template' => 'https://bitbucket.org/wearerequired/traduttore/src/master/%file%#L%line%', @@ -89,7 +89,7 @@ public function test_get_name(): void { * @param false $preempt Whether to preempt an HTTP request's return value. Default false. * @param mixed $r HTTP request arguments. * @param string $url The request URL. - * @return array|false Response data. + * @return array{response: array{ code: int }, body: string}|false Response data. */ public function mock_repository_visibility_request( $preempt, $r, $url ) { if ( BitbucketRepository::API_BASE . '/repositories/wearerequired/traduttore' === $url ) { diff --git a/tests/phpunit/tests/Repository/GitHub.php b/tests/phpunit/tests/Repository/GitHub.php index 53b110e3..acc37f7f 100644 --- a/tests/phpunit/tests/Repository/GitHub.php +++ b/tests/phpunit/tests/Repository/GitHub.php @@ -30,7 +30,7 @@ public function setUp(): void { parent::setUp(); $this->project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Project', ] @@ -54,7 +54,7 @@ public function test_get_name_falls_back_to_project_slug(): void { public function test_get_name_falls_back_to_source_url_template(): void { $project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Project', 'source_url_template' => 'https://github.com/wearerequired/traduttore/blob/master/%file%#L%line%', @@ -69,7 +69,7 @@ public function test_get_name_falls_back_to_source_url_template(): void { public function test_get_name_falls_back_to_different_source_url_template(): void { $project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Project', 'source_url_template' => 'https://github.com/wearerequired/traduttore/tree/master/%file%#L%line%', @@ -104,7 +104,7 @@ public function test_get_name(): void { * @param false $preempt Whether to preempt an HTTP request's return value. Default false. * @param mixed $r HTTP request arguments. * @param string $url The request URL. - * @return array|false Response data. + * @return array{response: array{ code: int }, body: string}|false Response data. */ public function mock_repository_visibility_request( $preempt, $r, $url ) { if ( GitHubRepository::API_BASE . '/repos/wearerequired/traduttore' === $url ) { diff --git a/tests/phpunit/tests/Repository/GitLab.php b/tests/phpunit/tests/Repository/GitLab.php index cafaf07f..636c340e 100644 --- a/tests/phpunit/tests/Repository/GitLab.php +++ b/tests/phpunit/tests/Repository/GitLab.php @@ -30,7 +30,7 @@ public function setUp(): void { parent::setUp(); $this->project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Project', ] @@ -54,7 +54,7 @@ public function test_get_name_falls_back_to_project_slug(): void { public function test_get_name_falls_back_to_source_url_template(): void { $project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Project', 'source_url_template' => 'https://gitlab.com/wearerequired/traduttore/blob/master/%file%#L%line%', @@ -103,7 +103,7 @@ public function test_get_host(): void { * @param false $preempt Whether to preempt an HTTP request's return value. Default false. * @param mixed $r HTTP request arguments. * @param string $url The request URL. - * @return array|false Response data. + * @return array{response: array{ code: int }, body: string}|false Response data. */ public function mock_repository_visibility_request( $preempt, $r, $url ) { if ( GitLabRepository::API_BASE . '/projects/wearerequired%2Ftraduttore' === $url ) { diff --git a/tests/phpunit/tests/RepositoryFactory.php b/tests/phpunit/tests/RepositoryFactory.php index c431d010..43b171f4 100644 --- a/tests/phpunit/tests/RepositoryFactory.php +++ b/tests/phpunit/tests/RepositoryFactory.php @@ -18,7 +18,7 @@ class RepositoryFactory extends TestCase { public function test_get_unknown_repository(): void { $factory = new Factory(); $project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Project', ] @@ -31,7 +31,7 @@ public function test_get_unknown_repository(): void { public function test_get_unknown_repository_by_type(): void { $factory = new Factory(); $project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Project', ] @@ -46,7 +46,7 @@ public function test_get_unknown_repository_by_type(): void { public function test_get_bitbucket_repository_by_type(): void { $factory = new Factory(); $project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Project', ] @@ -61,7 +61,7 @@ public function test_get_bitbucket_repository_by_type(): void { public function test_get_bitbucket_repository_by_url(): void { $factory = new Factory(); $project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Project', ] @@ -76,7 +76,7 @@ public function test_get_bitbucket_repository_by_url(): void { public function test_get_bitbucket_repository_by_source_url_template(): void { $factory = new Factory(); $project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Project', 'source_url_template' => 'https://bitbucket.org/wearerequired/traduttore/src/master/%file%#L%line%', @@ -90,7 +90,7 @@ public function test_get_bitbucket_repository_by_source_url_template(): void { public function test_get_github_repository_by_type(): void { $factory = new Factory(); $project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Project', ] @@ -105,7 +105,7 @@ public function test_get_github_repository_by_type(): void { public function test_get_github_repository_by_url(): void { $factory = new Factory(); $project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Project', ] @@ -120,7 +120,7 @@ public function test_get_github_repository_by_url(): void { public function test_get_github_repository_by_source_url_template(): void { $factory = new Factory(); $project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Project', 'source_url_template' => 'https://github.com/wearerequired/traduttore/blob/master/%file%#L%line%', @@ -134,7 +134,7 @@ public function test_get_github_repository_by_source_url_template(): void { public function test_get_gitlab_repository_by_type(): void { $factory = new Factory(); $project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Project', ] @@ -149,7 +149,7 @@ public function test_get_gitlab_repository_by_type(): void { public function test_get_gitlab_repository_by_source_url_template(): void { $factory = new Factory(); $project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Project', 'source_url_template' => 'https://gitlab.com/wearerequired/traduttore/blob/master/%file%#L%line%', diff --git a/tests/phpunit/tests/Runner.php b/tests/phpunit/tests/Runner.php index b8e939aa..5b963616 100644 --- a/tests/phpunit/tests/Runner.php +++ b/tests/phpunit/tests/Runner.php @@ -35,7 +35,7 @@ public function setUp(): void { parent::setUp(); $this->project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Sample Project', 'slug' => 'sample-project', diff --git a/tests/phpunit/tests/TestCase.php b/tests/phpunit/tests/TestCase.php index c4555a7d..f0bd88a6 100644 --- a/tests/phpunit/tests/TestCase.php +++ b/tests/phpunit/tests/TestCase.php @@ -7,6 +7,7 @@ namespace Required\Traduttore\Tests; +use GP_UnitTest_Factory; use GP_UnitTestCase; use WP_Error; use WP_REST_Response; @@ -15,6 +16,19 @@ * Base TestCase class. */ class TestCase extends GP_UnitTestCase { + /** + * Fetches the factory object for generating WordPress fixtures. + * + * @return GP_UnitTest_Factory The fixture factory. + */ + protected static function factory(): GP_UnitTest_Factory { + static $factory = null; + if ( ! $factory ) { + $factory = new GP_UnitTest_Factory(); + } + return $factory; + } + /** * @see WP_Test_REST_TestCase * @@ -31,6 +45,7 @@ protected function assertErrorResponse( $code, $response, $status = null ): void $this->assertSame( $code, $response->get_error_code() ); if ( null !== $status ) { $data = $response->get_error_data(); + $this->assertIsArray( $data ); $this->assertArrayHasKey( 'status', $data ); $this->assertSame( $status, $data['status'] ); } diff --git a/tests/phpunit/tests/TranslationApiRoute.php b/tests/phpunit/tests/TranslationApiRoute.php index b8d19698..f9f63d02 100644 --- a/tests/phpunit/tests/TranslationApiRoute.php +++ b/tests/phpunit/tests/TranslationApiRoute.php @@ -7,6 +7,9 @@ namespace Required\Traduttore\Tests; +use GP_Locale; +use GP_Translation_Set; +use GP_UnitTest_Factory; use ReflectionClass; use GP; use GP_UnitTestCase_Route; @@ -17,22 +20,32 @@ * Test cases for \Required\Traduttore\TranslationApiRoute. */ class TranslationApiRoute extends GP_UnitTestCase_Route { - public $route_class = Route::class; - /** - * @var \GP_Translation_Set + * @var class-string */ - protected $translation_set; + public $route_class = Route::class; + + protected GP_Translation_Set $translation_set; + + protected GP_Locale $locale; /** - * @var \GP_Locale + * Fetches the factory object for generating WordPress fixtures. + * + * @return GP_UnitTest_Factory The fixture factory. */ - protected $locale; + protected static function factory(): GP_UnitTest_Factory { + static $factory = null; + if ( ! $factory ) { + $factory = new GP_UnitTest_Factory(); + } + return $factory; + } public function setUp(): void { parent::setUp(); - $this->locale = $this->factory->locale->create( + $this->locale = $this->factory()->locale->create( [ 'english_name' => 'German', 'native_name' => 'Deutsch', @@ -41,7 +54,7 @@ public function setUp(): void { ] ); - $this->translation_set = $this->factory->translation_set->create_with_project( + $this->translation_set = $this->factory()->translation_set->create_with_project( [ 'locale' => $this->locale->slug, ], @@ -52,7 +65,6 @@ public function setUp(): void { } public function tearDown(): void { - /* @var \WP_Filesystem_Base $wp_filesystem */ global $wp_filesystem; if ( ! $wp_filesystem ) { @@ -70,17 +82,32 @@ public function assert404(): void { $this->assertSame( 404, $this->route->http_status ); } - protected function get_route_callback( $project_path ) { + /** + * @param string $project_path + * + * @return array{error?: string, translations?: array>} Response data. + */ + protected function get_route_callback( string $project_path ): array { $route = $this->route; + /** + * Route response. + * + * @var string $response + */ $response = get_echo( function() use ( $route, $project_path ) { /** @var Route $route */ - return $route->route_callback( $project_path ); + $route->route_callback( $project_path ); } ); - return json_decode( $response, true ); + /** + * @var array{error?: string, translations?: array>} $result + */ + $result = (array) json_decode( $response, true ); + + return $result; } /** @@ -92,7 +119,14 @@ public function test_route_exists(): void { $property = $class->getProperty( 'urls' ); $property->setAccessible( true ); - $this->assertTrue( isset( $property->getValue( GP::$router )['get:/api/translations/(.+?)'] ) ); + /** + * Registered routes. + * + * @var array $routes + */ + $routes = $property->getValue( GP::$router ); + + $this->assertTrue( isset( $routes['get:/api/translations/(.+?)'] ) ); } public function test_invalid_project(): void { @@ -110,9 +144,9 @@ public function test_no_zip_files(): void { } public function test_one_zip_file(): void { - $original = $this->factory->original->create( [ 'project_id' => $this->translation_set->project_id ] ); + $original = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id ] ); - $this->factory->translation->create( + $this->factory()->translation->create( [ 'original_id' => $original->id, 'translation_set_id' => $this->translation_set->id, @@ -126,6 +160,7 @@ public function test_one_zip_file(): void { $response = $this->get_route_callback( 'foo-project' ); + $this->assertArrayHasKey( 'translations', $response ); $this->assertCount( 1, $response['translations'] ); $this->assertArrayHasKey( 'language', $response['translations'][0] ); $this->assertSame( 'de_DE', $response['translations'][0]['language'] ); @@ -140,9 +175,9 @@ public function test_one_zip_file(): void { } public function test_missing_build_time(): void { - $original = $this->factory->original->create( [ 'project_id' => $this->translation_set->project_id ] ); + $original = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id ] ); - $this->factory->translation->create( + $this->factory()->translation->create( [ 'original_id' => $original->id, 'translation_set_id' => $this->translation_set->id, @@ -158,16 +193,20 @@ public function test_missing_build_time(): void { $response = $this->get_route_callback( 'foo-project' ); + $this->assertArrayHasKey( 'translations', $response ); $this->assertCount( 0, $response['translations'] ); } public function test_uses_stored_project_version(): void { $project = ( new \Required\Traduttore\ProjectLocator( $this->translation_set->project_id ) )->get_project(); + + $this->assertInstanceOf( \Required\Traduttore\Project::class, $project); + $project->set_version( '1.2.3' ); - $original = $this->factory->original->create( [ 'project_id' => $this->translation_set->project_id ] ); + $original = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id ] ); - $this->factory->translation->create( + $this->factory()->translation->create( [ 'original_id' => $original->id, 'translation_set_id' => $this->translation_set->id, @@ -181,7 +220,7 @@ public function test_uses_stored_project_version(): void { $response = $this->get_route_callback( 'foo-project' ); - $this->assertCount( 1, $response['translations'] ); + $this->assertArrayHasKey( 'translations', $response ); $this->assertCount( 1, $response['translations'] ); $this->assertArrayHasKey( 'language', $response['translations'][0] ); $this->assertSame( 'de_DE', $response['translations'][0]['language'] ); diff --git a/tests/phpunit/tests/Updater.php b/tests/phpunit/tests/Updater.php index d9c4d237..3f9e63a4 100644 --- a/tests/phpunit/tests/Updater.php +++ b/tests/phpunit/tests/Updater.php @@ -30,7 +30,7 @@ public function setUp(): void { parent::setUp(); $this->project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Sample Project', 'slug' => 'sample-project', diff --git a/tests/phpunit/tests/WebhookHandler/Bitbucket.php b/tests/phpunit/tests/WebhookHandler/Bitbucket.php index 979d29cd..ad22b34e 100644 --- a/tests/phpunit/tests/WebhookHandler/Bitbucket.php +++ b/tests/phpunit/tests/WebhookHandler/Bitbucket.php @@ -10,22 +10,19 @@ use Required\Traduttore\Project; use Required\Traduttore\Repository; use Required\Traduttore\Tests\TestCase; -use \WP_REST_Request; +use WP_REST_Request; /** * Test cases for \Required\Traduttore\WebhookHandler\Bitbucket. */ class Bitbucket extends TestCase { - /** - * @var Project - */ - protected $project; + protected Project $project; public function setUp(): void { parent::setUp(); $this->project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Sample Project', 'source_url_template' => 'https://bitbucket.org/wearerequired/traduttore/blob/master/%file%#L%line%', @@ -52,9 +49,9 @@ public function test_invalid_event_header(): void { public function test_invalid_signature(): void { $request = new WP_REST_Request( 'POST', '/traduttore/v1/incoming-webhook' ); $request->set_body_params( [] ); - $signature = 'sha256=' . hash_hmac( 'sha256', wp_json_encode( $request->get_params() ), 'foo' ); + $signature = 'sha256=' . hash_hmac( 'sha256', (string) wp_json_encode( $request->get_params() ), 'foo' ); $request->add_header( 'x-event-key', 'repo:push' ); - $request->add_header( 'x-hub-signature', $signature ); + $request->add_header( 'x-hub-signature-256', $signature ); $response = rest_get_server()->dispatch( $request ); $this->assertErrorResponse( 'rest_forbidden', $response, 401 ); @@ -100,9 +97,9 @@ public function test_invalid_project(): void { ], ] ); - $signature = 'sha256=' . hash_hmac( 'sha256', wp_json_encode( $request->get_params() ), 'traduttore-test' ); + $signature = 'sha256=' . hash_hmac( 'sha256', (string) wp_json_encode( $request->get_params() ), 'traduttore-test' ); $request->add_header( 'x-event-key', 'repo:push' ); - $request->add_header( 'x-hub-signature', $signature ); + $request->add_header( 'x-hub-signature-256', $signature ); $response = rest_get_server()->dispatch( $request ); $this->assertErrorResponse( 404, $response ); @@ -125,9 +122,9 @@ public function test_valid_project(): void { ], ] ); - $signature = 'sha256=' . hash_hmac( 'sha256', wp_json_encode( $request->get_params() ), 'traduttore-test' ); + $signature = 'sha256=' . hash_hmac( 'sha256', (string) wp_json_encode( $request->get_params() ), 'traduttore-test' ); $request->add_header( 'x-event-key', 'repo:push' ); - $request->add_header( 'x-hub-signature', $signature ); + $request->add_header( 'x-hub-signature-256', $signature ); $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status() ); @@ -160,9 +157,9 @@ public function test_valid_mercurial_project(): void { ], ] ); - $signature = 'sha256=' . hash_hmac( 'sha256', wp_json_encode( $request->get_params() ), 'traduttore-test' ); + $signature = 'sha256=' . hash_hmac( 'sha256', (string) wp_json_encode( $request->get_params() ), 'traduttore-test' ); $request->add_header( 'x-event-key', 'repo:push' ); - $request->add_header( 'x-hub-signature', $signature ); + $request->add_header( 'x-hub-signature-256', $signature ); $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status() ); diff --git a/tests/phpunit/tests/WebhookHandler/GitHub.php b/tests/phpunit/tests/WebhookHandler/GitHub.php index 810bdd47..21b4360b 100644 --- a/tests/phpunit/tests/WebhookHandler/GitHub.php +++ b/tests/phpunit/tests/WebhookHandler/GitHub.php @@ -25,7 +25,7 @@ public function setUp(): void { parent::setUp(); $this->project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Sample Project', 'source_url_template' => 'https://github.com/wearerequired/traduttore/blob/master/%file%#L%line%', @@ -70,9 +70,9 @@ public function test_invalid_signature(): void { $request = new WP_REST_Request( 'POST', '/traduttore/v1/incoming-webhook' ); $request->add_header( 'Content-Type', 'application/json' ); $request->set_body( (string) wp_json_encode( [] ) ); - $signature = 'sha1=' . hash_hmac( 'sha1', $request->get_body(), 'foo' ); + $signature = 'sha256=' . hash_hmac( 'sha256', $request->get_body(), 'foo' ); $request->add_header( 'x-github-event', 'push' ); - $request->add_header( 'x-hub-signature', $signature ); + $request->add_header( 'x-hub-signature-256', $signature ); $response = rest_get_server()->dispatch( $request ); $this->assertErrorResponse( 'rest_forbidden', $response, 401 ); @@ -92,9 +92,9 @@ public function test_invalid_branch(): void { ] ) ); - $signature = 'sha1=' . hash_hmac( 'sha1', $request->get_body(), 'traduttore-test' ); + $signature = 'sha256=' . hash_hmac( 'sha256', $request->get_body(), 'traduttore-test' ); $request->add_header( 'x-github-event', 'push' ); - $request->add_header( 'x-hub-signature', $signature ); + $request->add_header( 'x-hub-signature-256', $signature ); $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status() ); @@ -120,9 +120,9 @@ public function test_invalid_project(): void { ] ) ); - $signature = 'sha1=' . hash_hmac( 'sha1', $request->get_body(), 'traduttore-test' ); + $signature = 'sha256=' . hash_hmac( 'sha256', $request->get_body(), 'traduttore-test' ); $request->add_header( 'x-github-event', 'push' ); - $request->add_header( 'x-hub-signature', $signature ); + $request->add_header( 'x-hub-signature-256', $signature ); $response = rest_get_server()->dispatch( $request ); $this->assertErrorResponse( 404, $response ); @@ -138,9 +138,9 @@ public function test_invalid_request(): void { ] ) ); - $signature = 'sha1=' . hash_hmac( 'sha1', $request->get_body(), 'traduttore-test' ); + $signature = 'sha256=' . hash_hmac( 'sha256', $request->get_body(), 'traduttore-test' ); $request->add_header( 'x-github-event', 'push' ); - $request->add_header( 'x-hub-signature', $signature ); + $request->add_header( 'x-hub-signature-256', $signature ); $response = rest_get_server()->dispatch( $request ); $this->assertErrorResponse( 400, $response ); @@ -165,9 +165,9 @@ public function test_valid_project(): void { ] ) ); - $signature = 'sha1=' . hash_hmac( 'sha1', $request->get_body(), 'traduttore-test' ); + $signature = 'sha256=' . hash_hmac( 'sha256', $request->get_body(), 'traduttore-test' ); $request->add_header( 'x-github-event', 'push' ); - $request->add_header( 'x-hub-signature', $signature ); + $request->add_header( 'x-hub-signature-256', $signature ); $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status() ); @@ -201,9 +201,9 @@ public function test_valid_project_with_x_www_form_urlencoded_content_type(): vo $request->set_body_params( $data ); $request->set_body( http_build_query( $data ) ); - $signature = 'sha1=' . hash_hmac( 'sha1', $request->get_body(), 'traduttore-test' ); + $signature = 'sha256=' . hash_hmac( 'sha256', $request->get_body(), 'traduttore-test' ); $request->add_header( 'x-github-event', 'push' ); - $request->add_header( 'x-hub-signature', $signature ); + $request->add_header( 'x-hub-signature-256', $signature ); $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status() ); @@ -240,9 +240,9 @@ public function test_valid_project_custom_webhook_secret(): void { ] ) ); - $signature = 'sha1=' . hash_hmac( 'sha1', $request->get_body(), $secret ); + $signature = 'sha256=' . hash_hmac( 'sha256', $request->get_body(), $secret ); $request->add_header( 'x-github-event', 'push' ); - $request->add_header( 'x-hub-signature', $signature ); + $request->add_header( 'x-hub-signature-256', $signature ); $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status() ); diff --git a/tests/phpunit/tests/WebhookHandler/GitLab.php b/tests/phpunit/tests/WebhookHandler/GitLab.php index f4c2c00c..aaaa437f 100644 --- a/tests/phpunit/tests/WebhookHandler/GitLab.php +++ b/tests/phpunit/tests/WebhookHandler/GitLab.php @@ -25,7 +25,7 @@ public function setUp(): void { parent::setUp(); $this->project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Sample Project', 'source_url_template' => 'https://gitlab.com/wearerequired/traduttore/blob/master/%file%#L%line%', diff --git a/tests/phpunit/tests/WebhookHandler/LegacyGitHub.php b/tests/phpunit/tests/WebhookHandler/LegacyGitHub.php index 32bf0f93..8df7bd3b 100644 --- a/tests/phpunit/tests/WebhookHandler/LegacyGitHub.php +++ b/tests/phpunit/tests/WebhookHandler/LegacyGitHub.php @@ -10,22 +10,19 @@ use Required\Traduttore\Project; use Required\Traduttore\Repository; use Required\Traduttore\Tests\TestCase; -use \WP_REST_Request; +use WP_REST_Request; /** * Test cases for \Required\Traduttore\WebhookHandler\GitHub. */ class LegacyGitHub extends TestCase { - /** - * @var Project - */ - protected $project; + protected Project $project; public function setUp(): void { parent::setUp(); $this->project = new Project( - $this->factory->project->create( + $this->factory()->project->create( [ 'name' => 'Sample Project', 'source_url_template' => 'https://github.com/wearerequired/traduttore/blob/master/%file%#L%line%', @@ -70,9 +67,9 @@ public function test_invalid_signature(): void { $request = new WP_REST_Request( 'POST', '/github-webhook/v1/push-event' ); $request->add_header( 'Content-Type', 'application/json' ); $request->set_body( (string) wp_json_encode( [] ) ); - $signature = 'sha1=' . hash_hmac( 'sha1', $request->get_body(), 'foo' ); + $signature = 'sha256=' . hash_hmac( 'sha256', $request->get_body(), 'foo' ); $request->add_header( 'x-github-event', 'push' ); - $request->add_header( 'x-hub-signature', $signature ); + $request->add_header( 'x-hub-signature-256', $signature ); $response = rest_get_server()->dispatch( $request ); $this->assertErrorResponse( 'rest_forbidden', $response, 401 ); @@ -92,9 +89,9 @@ public function test_invalid_branch(): void { ] ) ); - $signature = 'sha1=' . hash_hmac( 'sha1', $request->get_body(), 'traduttore-test' ); + $signature = 'sha256=' . hash_hmac( 'sha256', $request->get_body(), 'traduttore-test' ); $request->add_header( 'x-github-event', 'push' ); - $request->add_header( 'x-hub-signature', $signature ); + $request->add_header( 'x-hub-signature-256', $signature ); $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status() ); @@ -120,9 +117,9 @@ public function test_invalid_project(): void { ] ) ); - $signature = 'sha1=' . hash_hmac( 'sha1', $request->get_body(), 'traduttore-test' ); + $signature = 'sha256=' . hash_hmac( 'sha256', $request->get_body(), 'traduttore-test' ); $request->add_header( 'x-github-event', 'push' ); - $request->add_header( 'x-hub-signature', $signature ); + $request->add_header( 'x-hub-signature-256', $signature ); $response = rest_get_server()->dispatch( $request ); $this->assertErrorResponse( 404, $response ); @@ -147,9 +144,9 @@ public function test_valid_project(): void { ] ) ); - $signature = 'sha1=' . hash_hmac( 'sha1', $request->get_body(), 'traduttore-test' ); + $signature = 'sha256=' . hash_hmac( 'sha256', $request->get_body(), 'traduttore-test' ); $request->add_header( 'x-github-event', 'push' ); - $request->add_header( 'x-hub-signature', $signature ); + $request->add_header( 'x-hub-signature-256', $signature ); $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status() ); @@ -186,9 +183,9 @@ public function test_valid_project_custom_webhook_secret(): void { ] ) ); - $signature = 'sha1=' . hash_hmac( 'sha1', $request->get_body(), $secret ); + $signature = 'sha256=' . hash_hmac( 'sha256', $request->get_body(), $secret ); $request->add_header( 'x-github-event', 'push' ); - $request->add_header( 'x-hub-signature', $signature ); + $request->add_header( 'x-hub-signature-256', $signature ); $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status() ); diff --git a/tests/phpunit/tests/ZipProvider.php b/tests/phpunit/tests/ZipProvider.php index b2962980..c5a89986 100644 --- a/tests/phpunit/tests/ZipProvider.php +++ b/tests/phpunit/tests/ZipProvider.php @@ -42,14 +42,14 @@ class ZipProvider extends TestCase { public function setUp(): void { parent::setUp(); - $this->locale = $this->factory->locale->create( + $this->locale = $this->factory()->locale->create( [ 'slug' => 'de', 'wp_locale' => 'de_DE', ] ); - $this->translation_set = $this->factory->translation_set->create_with_project( + $this->translation_set = $this->factory()->translation_set->create_with_project( [ 'locale' => $this->locale->slug, ], @@ -58,7 +58,7 @@ public function setUp(): void { ] ); - $this->sub_translation_set = $this->factory->translation_set->create_with_project( + $this->sub_translation_set = $this->factory()->translation_set->create_with_project( [ 'locale' => $this->locale->slug, ], @@ -68,7 +68,11 @@ public function setUp(): void { ] ); - $this->project = new \Required\Traduttore\Project( GP::$project->get( $this->translation_set->project_id ) ); + $gp_project = GP::$project->get( $this->translation_set->project_id ); + + $this->assertNotFalse( $gp_project ); + + $this->project = new \Required\Traduttore\Project( $gp_project ); } public function tearDown(): void { @@ -145,9 +149,9 @@ public function test_generate_zip_file_no_filesystem(): void { } public function test_generate_zip_file(): void { - $original = $this->factory->original->create( [ 'project_id' => $this->translation_set->project_id ] ); + $original = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id ] ); - $this->factory->translation->create( + $this->factory()->translation->create( [ 'original_id' => $original->id, 'translation_set_id' => $this->translation_set->id, @@ -165,9 +169,9 @@ public function test_generate_zip_file(): void { * @preserveGlobalState disabled */ public function test_generate_zip_file_missing_wp_filesystem(): void { - $original = $this->factory->original->create( [ 'project_id' => $this->translation_set->project_id ] ); + $original = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id ] ); - $this->factory->translation->create( + $this->factory()->translation->create( [ 'original_id' => $original->id, 'translation_set_id' => $this->translation_set->id, @@ -185,9 +189,9 @@ public function test_generate_zip_file_missing_wp_filesystem(): void { } public function test_replaces_existing_zip_file(): void { - $original = $this->factory->original->create( [ 'project_id' => $this->translation_set->project_id ] ); + $original = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id ] ); - $this->factory->translation->create( + $this->factory()->translation->create( [ 'original_id' => $original->id, 'translation_set_id' => $this->translation_set->id, @@ -219,9 +223,9 @@ public function test_replaces_existing_zip_file(): void { } public function test_get_last_build_time_after_zip_generation(): void { - $original = $this->factory->original->create( [ 'project_id' => $this->translation_set->project_id ] ); + $original = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id ] ); - $this->factory->translation->create( + $this->factory()->translation->create( [ 'original_id' => $original->id, 'translation_set_id' => $this->translation_set->id, @@ -237,9 +241,9 @@ public function test_get_last_build_time_after_zip_generation(): void { } public function test_remove_zip_file(): void { - $original = $this->factory->original->create( [ 'project_id' => $this->translation_set->project_id ] ); + $original = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id ] ); - $this->factory->translation->create( + $this->factory()->translation->create( [ 'original_id' => $original->id, 'translation_set_id' => $this->translation_set->id, @@ -255,9 +259,9 @@ public function test_remove_zip_file(): void { } public function test_remove_zip_file_resets_build_time(): void { - $original = $this->factory->original->create( [ 'project_id' => $this->translation_set->project_id ] ); + $original = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id ] ); - $this->factory->translation->create( + $this->factory()->translation->create( [ 'original_id' => $original->id, 'translation_set_id' => $this->translation_set->id, @@ -284,9 +288,9 @@ public function test_remove_zip_file_does_not_exist(): void { } public function test_remove_zip_file_no_filesystem(): void { - $original = $this->factory->original->create( [ 'project_id' => $this->translation_set->project_id ] ); + $original = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id ] ); - $this->factory->translation->create( + $this->factory()->translation->create( [ 'original_id' => $original->id, 'translation_set_id' => $this->translation_set->id, @@ -309,9 +313,12 @@ public function test_remove_zip_file_no_filesystem(): void { public function test_use_text_domain_for_translation_files(): void { $project = ( new ProjectLocator( $this->translation_set->project_id ) )->get_project(); - $original = $this->factory->original->create( [ 'project_id' => $this->translation_set->project_id ] ); - $this->factory->translation->create( + $this->assertInstanceOf( \Required\Traduttore\Project::class, $project ); + + $original = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id ] ); + + $this->factory()->translation->create( [ 'original_id' => $original->id, 'translation_set_id' => $this->translation_set->id, @@ -337,8 +344,11 @@ public function test_use_text_domain_for_translation_files(): void { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar for ( $i = 0; $i < $zip->numFiles; $i ++ ) { - $stat = $zip->statIndex( $i ); - $actual_files[] = $stat['name']; + $stat = $zip->statIndex( $i ); + + if ( $stat ) { + $actual_files[] = $stat['name']; + } } $zip->close(); @@ -380,11 +390,11 @@ public function test_schedule_generation_removes_existing_event(): void { } public function test_does_not_schedule_generation_after_saving_translation_for_inactive_project(): void { - $original = $this->factory->original->create( [ 'project_id' => $this->translation_set->project_id ] ); + $original = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id ] ); $translation_set_id = (int) $this->translation_set->id; /** @var \GP_Translation $translation */ - $translation = $this->factory->translation->create( + $translation = $this->factory()->translation->create( [ 'original_id' => $original->id, 'translation_set_id' => $this->translation_set->id, @@ -408,11 +418,11 @@ public function test_does_not_schedule_generation_after_saving_translation_for_i public function test_schedules_generation_after_saving_translation(): void { $this->project->get_project()->save( [ 'active' => 1 ] ); - $original = $this->factory->original->create( [ 'project_id' => $this->translation_set->project_id ] ); + $original = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id ] ); $translation_set_id = (int) $this->translation_set->id; /** @var \GP_Translation $translation */ - $translation = $this->factory->translation->create( + $translation = $this->factory()->translation->create( [ 'original_id' => $original->id, 'translation_set_id' => $this->translation_set->id, @@ -435,7 +445,7 @@ public function test_schedules_generation_after_saving_translation(): void { public function test_does_not_schedule_generation_after_importing_originals_for_inactive_project(): void { /** @var \GP_Original $original */ - $original = $this->factory->original->create( [ 'project_id' => $this->translation_set->project_id ] ); + $original = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id ] ); $before = wp_next_scheduled( 'traduttore.generate_zip', [ $this->translation_set->id ] ); @@ -453,7 +463,7 @@ public function test_schedules_generation_after_importing_originals(): void { $this->project->get_project()->save( [ 'active' => 1 ] ); /** @var \GP_Original $original */ - $original = $this->factory->original->create( [ 'project_id' => $this->translation_set->project_id ] ); + $original = $this->factory()->original->create( [ 'project_id' => $this->translation_set->project_id ] ); $before = wp_next_scheduled( 'traduttore.generate_zip', [ $this->translation_set->id ] );