diff --git a/inc/CLI/LanguagePackCommand.php b/inc/CLI/LanguagePackCommand.php index 9a68198..cba707e 100644 --- a/inc/CLI/LanguagePackCommand.php +++ b/inc/CLI/LanguagePackCommand.php @@ -162,8 +162,8 @@ public function list( array $args, array $assoc_args ): void { * @param string[] $assoc_args Associative args. */ public function build( array $args, array $assoc_args ): void { - $all = get_flag_value( $assoc_args, 'all', false ); - $force = get_flag_value( $assoc_args, 'force', false ); + $all = (bool) get_flag_value( $assoc_args, 'all', false ); + $force = (bool) get_flag_value( $assoc_args, 'force', false ); $projects = $this->check_optional_args_and_all( $args, $all ); if ( ! $projects ) { diff --git a/inc/CLI/ProjectCommand.php b/inc/CLI/ProjectCommand.php index 7000acc..62684b0 100644 --- a/inc/CLI/ProjectCommand.php +++ b/inc/CLI/ProjectCommand.php @@ -166,8 +166,8 @@ public function info( array $args, array $assoc_args ): void { * @param string[] $assoc_args Associative args. */ public function update( array $args, array $assoc_args ): void { - $delete = get_flag_value( $assoc_args, 'delete', false ); - $cached = get_flag_value( $assoc_args, 'cached', false ); + $delete = (bool) get_flag_value( $assoc_args, 'delete', false ); + $cached = (bool) get_flag_value( $assoc_args, 'cached', false ); $locator = new ProjectLocator( $args[0] ); $project = $locator->get_project(); diff --git a/inc/Configuration.php b/inc/Configuration.php index eaf4a8f..b2cb857 100644 --- a/inc/Configuration.php +++ b/inc/Configuration.php @@ -12,7 +12,7 @@ * * @since 3.0.0 * - * @phpstan-type ProjectConfig array{ mergeWith?: string, textDomain?: string,exclude?: string } + * @phpstan-type ProjectConfig array{ mergeWith?: string, textDomain?: string,exclude?: string[] } */ class Configuration { /** @@ -29,9 +29,9 @@ class Configuration { * * @since 3.0.0 * - * @var array Repository configuration. - * * @phpstan-var ProjectConfig + * + * @var array Repository configuration. */ protected $config = []; @@ -64,7 +64,9 @@ public function get_path(): string { * * @since 3.0.0 * - * @return array Repository configuration. + * @phpstan-return ProjectConfig + * + * @return array Repository configuration. */ public function get_config(): array { return $this->config; @@ -75,8 +77,12 @@ public function get_config(): array { * * @since 3.0.0 * + * @phpstan-template T of key-of + * @phpstan-param T $key + * @phpstan-return ProjectConfig[T] | null + * * @param string $key Config key. - * @return mixed|null Config value. + * @return string|string[]|null Config value. */ public function get_config_value( string $key ) { if ( isset( $this->config[ $key ] ) ) { @@ -91,15 +97,21 @@ public function get_config_value( string $key ) { * * @since 3.0.0 * - * @return array> Configuration data if found. - * * @phpstan-return ProjectConfig + * + * @return array Configuration data if found. */ protected function load_config(): array { $config_file = trailingslashit( $this->path ) . 'traduttore.json'; $composer_file = trailingslashit( $this->path ) . 'composer.json'; if ( file_exists( $config_file ) ) { + /** + * Traduttore configuration. + * + * @phpstan-var ProjectConfig $config + * @var array $config + */ $config = json_decode( (string) file_get_contents( $config_file ), true ); if ( $config ) { @@ -108,6 +120,12 @@ protected function load_config(): array { } if ( file_exists( $composer_file ) ) { + /** + * Composer configuration. + * + * @phpstan-var array{extra?: array{ traduttore?: ProjectConfig } } $config + * @var array{extra?: array{ traduttore?: array } } $config + */ $config = json_decode( (string) file_get_contents( $composer_file ), true ); if ( $config && isset( $config['extra']['traduttore'] ) ) { diff --git a/inc/Export.php b/inc/Export.php index 5623daa..45ef7c7 100644 --- a/inc/Export.php +++ b/inc/Export.php @@ -10,7 +10,7 @@ use GP; use GP_Locales; use GP_Translation_Set; -use http\Exception\InvalidArgumentException; +use InvalidArgumentException; /** * Export strings to translation files in PO, MO, and JSON format. @@ -228,7 +228,7 @@ protected function build_json_files( array $mapping ): void { $contents = $format->print_exported_file( $this->project->get_project(), $this->locale, $this->translation_set, $entries ); // Add comment with file reference for debugging. - $contents_decoded = json_decode( $contents ); + $contents_decoded = (object) json_decode( $contents ); $contents_decoded->comment = [ 'reference' => $file ]; $contents = (string) wp_json_encode( $contents_decoded ); diff --git a/inc/Project.php b/inc/Project.php index d00a83b..2ee33b3 100644 --- a/inc/Project.php +++ b/inc/Project.php @@ -190,6 +190,11 @@ public function get_source_url_template(): ?string { * @return string|null Repository type if stored, null otherwise. */ public function get_repository_type(): ?string { + /** + * Project type. + * + * @var string|false $type + */ $type = gp_get_meta( 'project', $this->project->id, static::REPOSITORY_TYPE_KEY ); return $type ?: null; @@ -215,6 +220,11 @@ public function set_repository_type( string $type ): bool { * @return null|string VCS type if stored, null otherwise. */ public function get_repository_vcs_type(): ?string { + /** + * VCS type. + * + * @var string|false $type + */ $type = gp_get_meta( 'project', $this->project->id, static::REPOSITORY_VCS_TYPE_KEY ); return $type ?: null; @@ -240,6 +250,11 @@ public function set_repository_vcs_type( string $type ): bool { * @return null|string Repository URL if stored, null otherwise. */ public function get_repository_url(): ?string { + /** + * Repository URL. + * + * @var string|false $url + */ $url = gp_get_meta( 'project', $this->project->id, static::REPOSITORY_URL_KEY ); return $url ?: null; @@ -265,6 +280,11 @@ public function set_repository_url( string $url ): bool { * @return null|string Repository name if stored, null otherwise. */ public function get_repository_name(): ?string { + /** + * Repository name. + * + * @var string|false $name + */ $name = gp_get_meta( 'project', $this->project->id, static::REPOSITORY_NAME_KEY ); return $name ?: null; @@ -290,6 +310,11 @@ public function set_repository_name( string $name ): bool { * @return null|string Repository visibility if stored, null otherwise. */ public function get_repository_visibility(): ?string { + /** + * Repository visibility. + * + * @var string|false $visibility + */ $visibility = gp_get_meta( 'project', $this->project->id, static::REPOSITORY_VISIBILITY_KEY ); return $visibility ?: null; @@ -313,6 +338,11 @@ public function set_repository_visibility( string $visibility ): bool { * @return null|string Repository SSH URL if stored, null otherwise. */ public function get_repository_ssh_url(): ?string { + /** + * Repository SSH URL. + * + * @var string|false $url + */ $url = gp_get_meta( 'project', $this->project->id, static::REPOSITORY_SSH_URL_KEY ); return $url ?: null; @@ -338,6 +368,11 @@ public function set_repository_ssh_url( string $url ): bool { * @return null|string Repository HTTPS URL if stored, null otherwise. */ public function get_repository_https_url(): ?string { + /** + * Repository HTTPS URL. + * + * @var string|false $url + */ $url = gp_get_meta( 'project', $this->project->id, static::REPOSITORY_HTTPS_URL_KEY ); return $url ?: null; @@ -363,6 +398,11 @@ public function set_repository_https_url( string $url ): bool { * @return null|string Webhook sync secret if stored, null otherwise. */ public function get_repository_webhook_secret(): ?string { + /** + * Repository webhook secret. + * + * @var string|false $name + */ $name = gp_get_meta( 'project', $this->project->id, static::REPOSITORY_WEBHOOK_SECRET_KEY ); return $name ?: null; @@ -388,6 +428,11 @@ public function set_repository_webhook_secret( string $secret ): bool { * @return null|string Text domain if stored, null otherwise. */ public function get_text_domain(): ?string { + /** + * Project text domain + * + * @var string|false $name + */ $name = gp_get_meta( 'project', $this->project->id, static::TEXT_DOMAIN_KEY ); return $name ?: null; @@ -413,6 +458,11 @@ public function set_text_domain( string $name ): bool { * @return null|\DateTime Last updated time if stored, null otherwise. */ public function get_last_updated_time(): ?DateTime { + /** + * Project last updated time. + * + * @var string|false $time + */ $time = gp_get_meta( 'project', $this->project->id, static::UPDATE_TIME_KEY ); return $time ? new DateTime( $time, new DateTimeZone( 'UTC' ) ) : null; @@ -438,6 +488,11 @@ public function set_last_updated_time( DateTime $time ): bool { * @return null|string Version number if stored, null otherwise. */ public function get_version(): ?string { + /** + * Project version number. + * + * @var string|false $version + */ $version = gp_get_meta( 'project', $this->project->id, static::VERSION_KEY ); return $version ?: null; diff --git a/inc/ProjectLocator.php b/inc/ProjectLocator.php index aa9c6a6..556def8 100644 --- a/inc/ProjectLocator.php +++ b/inc/ProjectLocator.php @@ -9,7 +9,6 @@ use GP; use GP_Project; -use http\Exception\InvalidArgumentException; /** * Helper class to find a GlotPress project based on path, ID, or GitHub repository URL. @@ -22,7 +21,7 @@ class ProjectLocator { * * @since 2.0.0 * - * @var \Required\Traduttore\Project Project instance. + * @var \Required\Traduttore\Project|null Project instance. */ protected $project; @@ -31,16 +30,10 @@ class ProjectLocator { * * @since 2.0.0 * - * @param mixed $project Possible GlotPress project ID or path or source code repository path. + * @param int|string|Project|GP_Project $project Possible GlotPress project ID or path or source code repository path. */ public function __construct( $project ) { - $found = $this->find_project( $project ); - - if ( ! $found ) { - throw new InvalidArgumentException( __( 'Project not found', 'traduttore' ) ); - } - - $this->project = $found; + $this->project = $this->find_project( $project ); } /** @@ -59,7 +52,7 @@ public function get_project(): ?Project { * * @since 2.0.0 * - * @param mixed $project Possible GlotPress project ID or path or source code repository path. + * @param int|string|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 { @@ -82,15 +75,15 @@ protected function find_project( $project ): ?Project { } if ( ! $found ) { - $found = $this->find_by_repository_name( $project ); + $found = $this->find_by_repository_name( (string) $project ); } if ( ! $found ) { - $found = $this->find_by_repository_url( $project ); + $found = $this->find_by_repository_url( (string) $project ); } if ( ! $found ) { - $found = $this->find_by_source_url_template( $project ); + $found = $this->find_by_source_url_template( (string) $project ); } return $found ? new Project( $found ) : null; diff --git a/inc/WebhookHandler/GitHub.php b/inc/WebhookHandler/GitHub.php index c60d8e5..6fa4138 100644 --- a/inc/WebhookHandler/GitHub.php +++ b/inc/WebhookHandler/GitHub.php @@ -54,7 +54,7 @@ public function permission_callback(): ?bool { return false; } - $payload_signature = 'sha1=' . hash_hmac( 'sha1', (string) wp_json_encode( $params ), $secret ); + $payload_signature = 'sha1=' . hash_hmac( 'sha1', $this->request->get_body(), $secret ); return hash_equals( $token, $payload_signature ); } @@ -75,11 +75,18 @@ public function callback() { $params = $this->request->get_params(); $content_type = $this->request->get_content_type(); + // See https://developer.github.com/webhooks/creating/#content-type. if ( ! empty( $content_type ) && 'application/x-www-form-urlencoded' === $content_type['value'] ) { $params = json_decode( $params['payload'], true ); } + /** + * Request params. + * + * @var array{repository: array{ default_branch?: string, html_url: string, full_name: string, ssh_url: string, clone_url: string, private: bool }, ref: string } $params + */ + if ( ! isset( $params['repository']['default_branch'] ) ) { return new \WP_Error( '400', 'Request incomplete', [ 'status' => 400 ] ); } diff --git a/inc/ZipProvider.php b/inc/ZipProvider.php index 336aaa6..7c3fb28 100644 --- a/inc/ZipProvider.php +++ b/inc/ZipProvider.php @@ -12,7 +12,7 @@ use GP; use GP_Locales; use GP_Translation_Set; -use http\Exception\InvalidArgumentException; +use InvalidArgumentException; use ZipArchive; /** @@ -265,6 +265,11 @@ protected function get_zip_filename(): string { * @return \DateTime Last build time. */ public function get_last_build_time(): ?DateTime { + /** + * Build time. + * + * @var string|false $meta + */ $meta = gp_get_meta( 'translation_set', $this->translation_set->id, static::BUILD_TIME_KEY ); return $meta ? new DateTime( $meta, new DateTimeZone( 'UTC' ) ) : null; diff --git a/phpstan.neon.dist b/phpstan.neon.dist index b52330f..ed04ac1 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,5 +1,5 @@ parameters: - level: 8 + level: 9 inferPrivatePropertyTypeFromConstructor: true bootstrapFiles: - tests/phpstan/bootstrap.php diff --git a/tests/phpunit/tests/WebhookHandler/GitHub.php b/tests/phpunit/tests/WebhookHandler/GitHub.php index b082da5..810bdd4 100644 --- a/tests/phpunit/tests/WebhookHandler/GitHub.php +++ b/tests/phpunit/tests/WebhookHandler/GitHub.php @@ -68,8 +68,9 @@ public function test_missing_signature(): void { public function test_invalid_signature(): void { $request = new WP_REST_Request( 'POST', '/traduttore/v1/incoming-webhook' ); - $request->set_body_params( [] ); - $signature = 'sha1=' . hash_hmac( 'sha1', wp_json_encode( $request->get_params() ), 'foo' ); + $request->add_header( 'Content-Type', 'application/json' ); + $request->set_body( (string) wp_json_encode( [] ) ); + $signature = 'sha1=' . hash_hmac( 'sha1', $request->get_body(), 'foo' ); $request->add_header( 'x-github-event', 'push' ); $request->add_header( 'x-hub-signature', $signature ); $response = rest_get_server()->dispatch( $request ); @@ -79,16 +80,19 @@ public function test_invalid_signature(): void { public function test_invalid_branch(): void { $request = new WP_REST_Request( 'POST', '/traduttore/v1/incoming-webhook' ); - $request->set_body_params( - [ - 'ref' => 'refs/heads/master', - 'repository' => [ - 'html_url' => 'https://github.com/wearerequired/traduttore', - 'default_branch' => 'develop', - ], - ] + $request->add_header( 'Content-Type', 'application/json' ); + $request->set_body( + (string) wp_json_encode( + [ + 'ref' => 'refs/heads/master', + 'repository' => [ + 'html_url' => 'https://github.com/wearerequired/traduttore', + 'default_branch' => 'develop', + ], + ] + ) ); - $signature = 'sha1=' . hash_hmac( 'sha1', wp_json_encode( $request->get_params() ), 'traduttore-test' ); + $signature = 'sha1=' . hash_hmac( 'sha1', $request->get_body(), 'traduttore-test' ); $request->add_header( 'x-github-event', 'push' ); $request->add_header( 'x-hub-signature', $signature ); $response = rest_get_server()->dispatch( $request ); @@ -99,21 +103,24 @@ public function test_invalid_branch(): void { public function test_invalid_project(): void { $request = new WP_REST_Request( 'POST', '/traduttore/v1/incoming-webhook' ); - $request->set_body_params( - [ - 'ref' => 'refs/heads/master', - 'repository' => [ - 'default_branch' => 'master', - 'full_name' => 'wearerequired/not-traduttore', - 'html_url' => 'https://github.com/wearerequired/not-traduttore', - 'ssh_url' => 'git@github.com:wearerequired/not-traduttore.git', - 'clone_url' => 'https://github.com/wearerequired/not-traduttore.git', - 'url' => 'https://github.com/wearerequired/not-traduttore', - 'private' => false, - ], - ] + $request->add_header( 'Content-Type', 'application/json' ); + $request->set_body( + (string) wp_json_encode( + [ + 'ref' => 'refs/heads/master', + 'repository' => [ + 'default_branch' => 'master', + 'full_name' => 'wearerequired/not-traduttore', + 'html_url' => 'https://github.com/wearerequired/not-traduttore', + 'ssh_url' => 'git@github.com:wearerequired/not-traduttore.git', + 'clone_url' => 'https://github.com/wearerequired/not-traduttore.git', + 'url' => 'https://github.com/wearerequired/not-traduttore', + 'private' => false, + ], + ] + ) ); - $signature = 'sha1=' . hash_hmac( 'sha1', wp_json_encode( $request->get_params() ), 'traduttore-test' ); + $signature = 'sha1=' . hash_hmac( 'sha1', $request->get_body(), 'traduttore-test' ); $request->add_header( 'x-github-event', 'push' ); $request->add_header( 'x-hub-signature', $signature ); $response = rest_get_server()->dispatch( $request ); @@ -123,12 +130,15 @@ public function test_invalid_project(): void { public function test_invalid_request(): void { $request = new WP_REST_Request( 'POST', '/traduttore/v1/incoming-webhook' ); - $request->set_body_params( - [ - 'ref' => 'refs/heads/master', - ] + $request->add_header( 'Content-Type', 'application/json' ); + $request->set_body( + (string) wp_json_encode( + [ + 'ref' => 'refs/heads/master', + ] + ) ); - $signature = 'sha1=' . hash_hmac( 'sha1', wp_json_encode( $request->get_params() ), 'traduttore-test' ); + $signature = 'sha1=' . hash_hmac( 'sha1', $request->get_body(), 'traduttore-test' ); $request->add_header( 'x-github-event', 'push' ); $request->add_header( 'x-hub-signature', $signature ); $response = rest_get_server()->dispatch( $request ); @@ -138,21 +148,24 @@ public function test_invalid_request(): void { public function test_valid_project(): void { $request = new WP_REST_Request( 'POST', '/traduttore/v1/incoming-webhook' ); - $request->set_body_params( - [ - 'ref' => 'refs/heads/master', - 'repository' => [ - 'full_name' => 'wearerequired/traduttore', - 'default_branch' => 'master', - 'html_url' => 'https://github.com/wearerequired/traduttore', - 'ssh_url' => 'git@github.com:wearerequired/traduttore.git', - 'clone_url' => 'https://github.com/wearerequired/traduttore.git', - 'url' => 'https://github.com/wearerequired/traduttore', - 'private' => false, - ], - ] + $request->add_header( 'Content-Type', 'application/json' ); + $request->set_body( + (string) wp_json_encode( + [ + 'ref' => 'refs/heads/master', + 'repository' => [ + 'full_name' => 'wearerequired/traduttore', + 'default_branch' => 'master', + 'html_url' => 'https://github.com/wearerequired/traduttore', + 'ssh_url' => 'git@github.com:wearerequired/traduttore.git', + 'clone_url' => 'https://github.com/wearerequired/traduttore.git', + 'url' => 'https://github.com/wearerequired/traduttore', + 'private' => false, + ], + ] + ) ); - $signature = 'sha1=' . hash_hmac( 'sha1', wp_json_encode( $request->get_params() ), 'traduttore-test' ); + $signature = 'sha1=' . hash_hmac( 'sha1', $request->get_body(), 'traduttore-test' ); $request->add_header( 'x-github-event', 'push' ); $request->add_header( 'x-hub-signature', $signature ); $response = rest_get_server()->dispatch( $request ); @@ -171,23 +184,24 @@ public function test_valid_project(): void { public function test_valid_project_with_x_www_form_urlencoded_content_type(): void { $request = new WP_REST_Request( 'POST', '/traduttore/v1/incoming-webhook' ); $request->set_header( 'Content-Type', 'application/x-www-form-urlencoded' ); - $request->set_body_params( - [ - 'payload' => json_encode( [ - 'ref' => 'refs/heads/master', - 'repository' => [ - 'full_name' => 'wearerequired/traduttore', - 'default_branch' => 'master', - 'html_url' => 'https://github.com/wearerequired/traduttore', - 'ssh_url' => 'git@github.com:wearerequired/traduttore.git', - 'clone_url' => 'https://github.com/wearerequired/traduttore.git', - 'url' => 'https://github.com/wearerequired/traduttore', - 'private' => false, - ], - ] ) - ] - ); - $signature = 'sha1=' . hash_hmac( 'sha1', wp_json_encode( $request->get_params() ), 'traduttore-test' ); + $data = [ + 'payload' => json_encode( [ + 'ref' => 'refs/heads/master', + 'repository' => [ + 'full_name' => 'wearerequired/traduttore', + 'default_branch' => 'master', + 'html_url' => 'https://github.com/wearerequired/traduttore', + 'ssh_url' => 'git@github.com:wearerequired/traduttore.git', + 'clone_url' => 'https://github.com/wearerequired/traduttore.git', + 'url' => 'https://github.com/wearerequired/traduttore', + 'private' => false, + ], + ] ) + ]; + $request->set_body_params( $data ); + $request->set_body( http_build_query( $data ) ); + + $signature = 'sha1=' . hash_hmac( 'sha1', $request->get_body(), 'traduttore-test' ); $request->add_header( 'x-github-event', 'push' ); $request->add_header( 'x-hub-signature', $signature ); $response = rest_get_server()->dispatch( $request ); @@ -209,21 +223,24 @@ public function test_valid_project_custom_webhook_secret(): void { $this->project->set_repository_webhook_secret( $secret ); $request = new WP_REST_Request( 'POST', '/traduttore/v1/incoming-webhook' ); - $request->set_body_params( - [ - 'ref' => 'refs/heads/master', - 'repository' => [ - 'full_name' => 'wearerequired/traduttore', - 'default_branch' => 'master', - 'html_url' => 'https://github.com/wearerequired/traduttore', - 'ssh_url' => 'git@github.com:wearerequired/traduttore.git', - 'clone_url' => 'https://github.com/wearerequired/traduttore.git', - 'url' => 'https://github.com/wearerequired/traduttore', - 'private' => false, - ], - ] + $request->add_header( 'Content-Type', 'application/json' ); + $request->set_body( + (string) wp_json_encode( + [ + 'ref' => 'refs/heads/master', + 'repository' => [ + 'full_name' => 'wearerequired/traduttore', + 'default_branch' => 'master', + 'html_url' => 'https://github.com/wearerequired/traduttore', + 'ssh_url' => 'git@github.com:wearerequired/traduttore.git', + 'clone_url' => 'https://github.com/wearerequired/traduttore.git', + 'url' => 'https://github.com/wearerequired/traduttore', + 'private' => false, + ], + ] + ) ); - $signature = 'sha1=' . hash_hmac( 'sha1', wp_json_encode( $request->get_params() ), $secret ); + $signature = 'sha1=' . hash_hmac( 'sha1', $request->get_body(), $secret ); $request->add_header( 'x-github-event', 'push' ); $request->add_header( 'x-hub-signature', $signature ); $response = rest_get_server()->dispatch( $request ); diff --git a/tests/phpunit/tests/WebhookHandler/LegacyGitHub.php b/tests/phpunit/tests/WebhookHandler/LegacyGitHub.php index 474b4f2..32bf0f9 100644 --- a/tests/phpunit/tests/WebhookHandler/LegacyGitHub.php +++ b/tests/phpunit/tests/WebhookHandler/LegacyGitHub.php @@ -68,8 +68,9 @@ public function test_missing_signature(): void { public function test_invalid_signature(): void { $request = new WP_REST_Request( 'POST', '/github-webhook/v1/push-event' ); - $request->set_body_params( [] ); - $signature = 'sha1=' . hash_hmac( 'sha1', wp_json_encode( $request->get_params() ), 'foo' ); + $request->add_header( 'Content-Type', 'application/json' ); + $request->set_body( (string) wp_json_encode( [] ) ); + $signature = 'sha1=' . hash_hmac( 'sha1', $request->get_body(), 'foo' ); $request->add_header( 'x-github-event', 'push' ); $request->add_header( 'x-hub-signature', $signature ); $response = rest_get_server()->dispatch( $request ); @@ -79,16 +80,19 @@ public function test_invalid_signature(): void { public function test_invalid_branch(): void { $request = new WP_REST_Request( 'POST', '/github-webhook/v1/push-event' ); - $request->set_body_params( - [ - 'ref' => 'refs/heads/master', - 'repository' => [ - 'html_url' => 'https://github.com/wearerequired/traduttore', - 'default_branch' => 'develop', - ], - ] + $request->add_header( 'Content-Type', 'application/json' ); + $request->set_body( + (string) wp_json_encode( + [ + 'ref' => 'refs/heads/master', + 'repository' => [ + 'html_url' => 'https://github.com/wearerequired/traduttore', + 'default_branch' => 'develop', + ], + ] + ) ); - $signature = 'sha1=' . hash_hmac( 'sha1', wp_json_encode( $request->get_params() ), 'traduttore-test' ); + $signature = 'sha1=' . hash_hmac( 'sha1', $request->get_body(), 'traduttore-test' ); $request->add_header( 'x-github-event', 'push' ); $request->add_header( 'x-hub-signature', $signature ); $response = rest_get_server()->dispatch( $request ); @@ -99,21 +103,24 @@ public function test_invalid_branch(): void { public function test_invalid_project(): void { $request = new WP_REST_Request( 'POST', '/github-webhook/v1/push-event' ); - $request->set_body_params( - [ - 'ref' => 'refs/heads/master', - 'repository' => [ - 'default_branch' => 'master', - 'full_name' => 'wearerequired/not-traduttore', - 'html_url' => 'https://github.com/wearerequired/not-traduttore', - 'ssh_url' => 'git@github.com:wearerequired/not-traduttore.git', - 'clone_url' => 'https://github.com/wearerequired/not-traduttore.git', - 'url' => 'https://github.com/wearerequired/not-traduttore', - 'private' => false, - ], - ] + $request->add_header( 'Content-Type', 'application/json' ); + $request->set_body( + (string) wp_json_encode( + [ + 'ref' => 'refs/heads/master', + 'repository' => [ + 'default_branch' => 'master', + 'full_name' => 'wearerequired/not-traduttore', + 'html_url' => 'https://github.com/wearerequired/not-traduttore', + 'ssh_url' => 'git@github.com:wearerequired/not-traduttore.git', + 'clone_url' => 'https://github.com/wearerequired/not-traduttore.git', + 'url' => 'https://github.com/wearerequired/not-traduttore', + 'private' => false, + ], + ] + ) ); - $signature = 'sha1=' . hash_hmac( 'sha1', wp_json_encode( $request->get_params() ), 'traduttore-test' ); + $signature = 'sha1=' . hash_hmac( 'sha1', $request->get_body(), 'traduttore-test' ); $request->add_header( 'x-github-event', 'push' ); $request->add_header( 'x-hub-signature', $signature ); $response = rest_get_server()->dispatch( $request ); @@ -123,21 +130,24 @@ public function test_invalid_project(): void { public function test_valid_project(): void { $request = new WP_REST_Request( 'POST', '/github-webhook/v1/push-event' ); - $request->set_body_params( - [ - 'ref' => 'refs/heads/master', - 'repository' => [ - 'full_name' => 'wearerequired/traduttore', - 'default_branch' => 'master', - 'html_url' => 'https://github.com/wearerequired/traduttore', - 'ssh_url' => 'git@github.com:wearerequired/traduttore.git', - 'clone_url' => 'https://github.com/wearerequired/traduttore.git', - 'url' => 'https://github.com/wearerequired/traduttore', - 'private' => false, - ], - ] + $request->add_header( 'Content-Type', 'application/json' ); + $request->set_body( + (string) wp_json_encode( + [ + 'ref' => 'refs/heads/master', + 'repository' => [ + 'full_name' => 'wearerequired/traduttore', + 'default_branch' => 'master', + 'html_url' => 'https://github.com/wearerequired/traduttore', + 'ssh_url' => 'git@github.com:wearerequired/traduttore.git', + 'clone_url' => 'https://github.com/wearerequired/traduttore.git', + 'url' => 'https://github.com/wearerequired/traduttore', + 'private' => false, + ], + ] + ) ); - $signature = 'sha1=' . hash_hmac( 'sha1', wp_json_encode( $request->get_params() ), 'traduttore-test' ); + $signature = 'sha1=' . hash_hmac( 'sha1', $request->get_body(), 'traduttore-test' ); $request->add_header( 'x-github-event', 'push' ); $request->add_header( 'x-hub-signature', $signature ); $response = rest_get_server()->dispatch( $request ); @@ -159,21 +169,24 @@ public function test_valid_project_custom_webhook_secret(): void { $this->project->set_repository_webhook_secret( $secret ); $request = new WP_REST_Request( 'POST', '/github-webhook/v1/push-event' ); - $request->set_body_params( - [ - 'ref' => 'refs/heads/master', - 'repository' => [ - 'full_name' => 'wearerequired/traduttore', - 'default_branch' => 'master', - 'html_url' => 'https://github.com/wearerequired/traduttore', - 'ssh_url' => 'git@github.com:wearerequired/traduttore.git', - 'clone_url' => 'https://github.com/wearerequired/traduttore.git', - 'url' => 'https://github.com/wearerequired/traduttore', - 'private' => false, - ], - ] + $request->add_header( 'Content-Type', 'application/json' ); + $request->set_body( + (string) wp_json_encode( + [ + 'ref' => 'refs/heads/master', + 'repository' => [ + 'full_name' => 'wearerequired/traduttore', + 'default_branch' => 'master', + 'html_url' => 'https://github.com/wearerequired/traduttore', + 'ssh_url' => 'git@github.com:wearerequired/traduttore.git', + 'clone_url' => 'https://github.com/wearerequired/traduttore.git', + 'url' => 'https://github.com/wearerequired/traduttore', + 'private' => false, + ], + ] + ) ); - $signature = 'sha1=' . hash_hmac( 'sha1', wp_json_encode( $request->get_params() ), $secret ); + $signature = 'sha1=' . hash_hmac( 'sha1', $request->get_body(), $secret ); $request->add_header( 'x-github-event', 'push' ); $request->add_header( 'x-hub-signature', $signature ); $response = rest_get_server()->dispatch( $request );