Open
Description
Description
When I was using CreateResponse::fake() to create test fixtures for response api, I've noticed the Fakeable trait's buildAttributes method improperly merges indexed arrays like output from the default fixtures with the provided override data, resulting in unexpected content in test responses.
Steps To Reproduce
// Create a fake response with specific output
$response = CreateResponse::fake([
'output' => [
[
'type' => 'message',
'id' => 'msg_1',
'role' => 'assistant',
'status' => 'completed',
'content' => [
[
'type' => 'output_text',
'text' => 'This is a test response',
'annotations' => [],
],
],
],
],
]);
// Actual output contains both the test data AND data from CreateResponseFixture.php
// Unexpected output like: "This is a test responseAs of today, March 9, 2025, one notable positive news story..."
OpenAI PHP Client Version
v0.13.0
PHP Version
8.4.0
Notes
Cursor suggested solution:
private static function buildAttributes(array $original, array $override): array
{
$new = [];
foreach ($original as $key => $entry) {
// Check if this is an array that should be replaced entirely rather than merged
if (isset($override[$key]) && is_array($entry) && is_array($override[$key]) &&
(in_array($key, ['output', 'tools', 'annotations']) || isset($override[$key][0]))) {
// For arrays of objects (indexed arrays), replace entirely instead of merging
$new[$key] = $override[$key];
} else {
// For other arrays, continue with recursive merging
$new[$key] = is_array($entry) ?
self::buildAttributes($entry, $override[$key] ?? []) :
$override[$key] ?? $entry;
}
unset($override[$key]);
}
// Add any remaining overrides
foreach ($override as $key => $value) {
$new[$key] = $value;
}
return $new;
}