Files
prautoblogger/tests/unit/Providers/RunwareImageSupportTest.php
peptiderepo 8bedecd2dd test: fix Runware tests to use real Encryption class path
The composer classmap autoloader loads the real PRAutoBlogger_Encryption
before our eval() stub runs, so class_exists() is always true and the stub
is never installed. Two consequences:

1. Provider tests set 'enc:fake-key' and the real decrypt() path ran,
   calling wp_salt() which isn't stubbed. Switched to plaintext keys
   so is_encrypted() short-circuits and no crypto runs.
2. Support test for the decrypt path now uses a real encrypt/decrypt
   round-trip with a stubbed wp_salt() returning a deterministic
   32-char salt. This exercises the actual code path users hit in
   production, not a lying stub.

Removes the dead eval() stubs that were being skipped anyway.
2026-04-21 15:59:36 +00:00

183 lines
6.4 KiB
PHP

<?php
/**
* Tests for PRAutoBlogger_Runware_Image_Support.
*
* Covers response parsing (URL extraction), dimension snapping to FLUX
* constraints, seed normalization, and API-key lookup.
*
* @package PRAutoBlogger\Tests\Providers
*/
namespace PRAutoBlogger\Tests\Providers;
use PRAutoBlogger\Tests\BaseTestCase;
use Brain\Monkey\Functions;
class RunwareImageSupportTest extends BaseTestCase {
protected function setUp(): void {
parent::setUp();
Functions\when( 'esc_html' )->returnArg();
Functions\when( 'esc_html__' )->returnArg();
Functions\when( '__' )->returnArg();
// Real PRAutoBlogger_Encryption uses wp_salt('auth') internally on the
// decrypt path. Stub it with a deterministic 32-char string so OpenSSL
// has a key to work with in the "enc:"-prefixed round-trip test.
Functions\when( 'wp_salt' )->justReturn( 'test-salt-32chars-aaaaaaaaaaaaaa' );
}
/** A well-formed imageInference entry returns its imageURL. */
public function test_extract_image_url_valid_response(): void {
$support = new \PRAutoBlogger_Runware_Image_Support();
$raw = wp_json_encode( [
'data' => [
[
'taskType' => 'imageInference',
'imageURL' => 'https://im.runware.ai/image/abc123.png',
],
],
] );
$this->assertSame(
'https://im.runware.ai/image/abc123.png',
$support->extract_image_url( $raw )
);
}
/** An errors[] array in the response causes a RuntimeException. */
public function test_extract_image_url_error_response_throws(): void {
$support = new \PRAutoBlogger_Runware_Image_Support();
$raw = wp_json_encode( [
'errors' => [
[ 'message' => 'invalid api key' ],
],
] );
$this->expectException( \RuntimeException::class );
$this->expectExceptionMessage( 'invalid api key' );
$support->extract_image_url( $raw );
}
/** Malformed JSON throws RuntimeException. */
public function test_extract_image_url_invalid_json_throws(): void {
$support = new \PRAutoBlogger_Runware_Image_Support();
$this->expectException( \RuntimeException::class );
$support->extract_image_url( 'not json at all' );
}
/** Data array present but no imageInference entry throws. */
public function test_extract_image_url_no_inference_entry_throws(): void {
$support = new \PRAutoBlogger_Runware_Image_Support();
$raw = wp_json_encode( [
'data' => [
[ 'taskType' => 'authentication' ],
],
] );
$this->expectException( \RuntimeException::class );
$support->extract_image_url( $raw );
}
/** imageInference present but empty imageURL throws. */
public function test_extract_image_url_empty_url_throws(): void {
$support = new \PRAutoBlogger_Runware_Image_Support();
$raw = wp_json_encode( [
'data' => [
[ 'taskType' => 'imageInference', 'imageURL' => '' ],
],
] );
$this->expectException( \RuntimeException::class );
$support->extract_image_url( $raw );
}
/** snap_dimension rounds to nearest multiple of 64. */
public function test_snap_dimension_rounds_to_64(): void {
$support = new \PRAutoBlogger_Runware_Image_Support();
$this->assertSame( 1216, $support->snap_dimension( 1200 ) );
$this->assertSame( 640, $support->snap_dimension( 632 ) );
$this->assertSame( 1024, $support->snap_dimension( 1024 ) );
$this->assertSame( 1024, $support->snap_dimension( 1050 ) );
}
/** snap_dimension clamps to minimum 512. */
public function test_snap_dimension_clamps_min(): void {
$support = new \PRAutoBlogger_Runware_Image_Support();
$this->assertSame( 512, $support->snap_dimension( 64 ) );
$this->assertSame( 512, $support->snap_dimension( 200 ) );
}
/** snap_dimension clamps to maximum 2048. */
public function test_snap_dimension_clamps_max(): void {
$support = new \PRAutoBlogger_Runware_Image_Support();
$this->assertSame( 2048, $support->snap_dimension( 4096 ) );
$this->assertSame( 2048, $support->snap_dimension( 2500 ) );
}
/** A valid positive seed passes through unchanged. */
public function test_normalize_seed_positive_passthrough(): void {
$support = new \PRAutoBlogger_Runware_Image_Support();
$this->assertSame( 42, $support->normalize_seed( 42 ) );
$this->assertSame( 1234567, $support->normalize_seed( 1234567 ) );
}
/** Null seed derives a positive integer. */
public function test_normalize_seed_null_derives_positive(): void {
$support = new \PRAutoBlogger_Runware_Image_Support();
$seed = $support->normalize_seed( null );
$this->assertGreaterThan( 0, $seed );
}
/** Zero seed is replaced with a derived positive integer. */
public function test_normalize_seed_zero_replaced(): void {
$support = new \PRAutoBlogger_Runware_Image_Support();
$seed = $support->normalize_seed( 0 );
$this->assertGreaterThan( 0, $seed );
}
/** Negative seed is replaced with a derived positive integer. */
public function test_normalize_seed_negative_replaced(): void {
$support = new \PRAutoBlogger_Runware_Image_Support();
$seed = $support->normalize_seed( -5 );
$this->assertGreaterThan( 0, $seed );
}
/** Missing API key option throws RuntimeException. */
public function test_get_api_key_missing_throws(): void {
Functions\when( 'get_option' )->alias( function ( $key, $default = false ) {
return $default;
} );
$support = new \PRAutoBlogger_Runware_Image_Support();
$this->expectException( \RuntimeException::class );
$support->get_api_key();
}
/** Encrypted key is decrypted on read (round-trips through real PRAutoBlogger_Encryption). */
public function test_get_api_key_decrypts_encrypted(): void {
$plaintext = 'rw-real-round-trip-key';
$cipher = \PRAutoBlogger_Encryption::encrypt( $plaintext );
$this->assertStringStartsWith( 'enc:', $cipher, 'encrypt() must return an enc:-prefixed value' );
Functions\when( 'get_option' )->alias( function ( $key, $default = false ) use ( $cipher ) {
if ( 'prautoblogger_runware_api_key' === $key ) {
return $cipher;
}
return $default;
} );
$support = new \PRAutoBlogger_Runware_Image_Support();
$this->assertSame( $plaintext, $support->get_api_key() );
}
/** A plaintext key (pre-migration) passes through unchanged. */
public function test_get_api_key_plaintext_passthrough(): void {
Functions\when( 'get_option' )->alias( function ( $key, $default = false ) {
if ( 'prautoblogger_runware_api_key' === $key ) {
return 'rw-plain-key';
}
return $default;
} );
$support = new \PRAutoBlogger_Runware_Image_Support();
$this->assertSame( 'rw-plain-key', $support->get_api_key() );
}
}