mirror of
https://github.com/usetrmnl/byos_laravel.git
synced 2026-01-13 15:07:49 +00:00
fix idx bug and add tests
This commit is contained in:
parent
e80814daa3
commit
c4480690a3
2 changed files with 89 additions and 98 deletions
|
|
@ -153,12 +153,13 @@ class Plugin extends Model
|
|||
|
||||
public function updateDataPayload(): void
|
||||
{
|
||||
if ($this->data_strategy === 'polling' && $this->polling_url) {
|
||||
|
||||
if ($this->data_strategy !== 'polling' || !$this->polling_url) {
|
||||
return;
|
||||
}
|
||||
$headers = ['User-Agent' => 'usetrmnl/byos_laravel', 'Accept' => 'application/json'];
|
||||
|
||||
// resolve headers
|
||||
if ($this->polling_header) {
|
||||
// Resolve Liquid variables in the polling header
|
||||
$resolvedHeader = $this->resolveLiquidVariables($this->polling_header);
|
||||
$headerLines = explode("\n", mb_trim($resolvedHeader));
|
||||
foreach ($headerLines as $line) {
|
||||
|
|
@ -169,90 +170,51 @@ class Plugin extends Model
|
|||
}
|
||||
}
|
||||
|
||||
// Resolve Liquid variables in the entire polling_url field first, then split by newline
|
||||
// resolve and clean URLs
|
||||
$resolvedPollingUrls = $this->resolveLiquidVariables($this->polling_url);
|
||||
$urls = array_filter(
|
||||
$urls = array_values(array_filter( // array_values ensures 0, 1, 2...
|
||||
array_map('trim', explode("\n", $resolvedPollingUrls)),
|
||||
fn ($url): bool => ! empty($url)
|
||||
);
|
||||
fn ($url): bool => filled($url)
|
||||
));
|
||||
|
||||
// If only one URL, use the original logic without nesting
|
||||
if (count($urls) === 1) {
|
||||
$url = reset($urls);
|
||||
$httpRequest = Http::withHeaders($headers);
|
||||
|
||||
if ($this->polling_verb === 'post' && $this->polling_body) {
|
||||
// Resolve Liquid variables in the polling body
|
||||
$resolvedBody = $this->resolveLiquidVariables($this->polling_body);
|
||||
$httpRequest = $httpRequest->withBody($resolvedBody);
|
||||
}
|
||||
|
||||
// URL is already resolved, use it directly
|
||||
$resolvedUrl = $url;
|
||||
|
||||
try {
|
||||
// Make the request based on the verb
|
||||
$httpResponse = $this->polling_verb === 'post' ? $httpRequest->post($resolvedUrl) : $httpRequest->get($resolvedUrl);
|
||||
|
||||
$response = $this->parseResponse($httpResponse);
|
||||
|
||||
$this->update([
|
||||
'data_payload' => $response,
|
||||
'data_payload_updated_at' => now(),
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
Log::warning("Failed to fetch data from URL {$resolvedUrl}: ".$e->getMessage());
|
||||
$this->update([
|
||||
'data_payload' => ['error' => 'Failed to fetch data'],
|
||||
'data_payload_updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Multiple URLs - use nested response logic
|
||||
$combinedResponse = [];
|
||||
|
||||
// Loop through all URLs (Handles 1 or many)
|
||||
foreach ($urls as $index => $url) {
|
||||
$httpRequest = Http::withHeaders($headers);
|
||||
|
||||
if ($this->polling_verb === 'post' && $this->polling_body) {
|
||||
// Resolve Liquid variables in the polling body
|
||||
$resolvedBody = $this->resolveLiquidVariables($this->polling_body);
|
||||
$httpRequest = $httpRequest->withBody($resolvedBody);
|
||||
}
|
||||
|
||||
// URL is already resolved, use it directly
|
||||
$resolvedUrl = $url;
|
||||
|
||||
try {
|
||||
// Make the request based on the verb
|
||||
$httpResponse = $this->polling_verb === 'post' ? $httpRequest->post($resolvedUrl) : $httpRequest->get($resolvedUrl);
|
||||
$httpResponse = ($this->polling_verb === 'post')
|
||||
? $httpRequest->post($url)
|
||||
: $httpRequest->get($url);
|
||||
|
||||
$response = $this->parseResponse($httpResponse);
|
||||
|
||||
// Check if response is an array at root level
|
||||
// Nest if it's a sequential array
|
||||
if (array_keys($response) === range(0, count($response) - 1)) {
|
||||
// Response is a sequential array, nest under .data
|
||||
$combinedResponse["IDX_{$index}"] = ['data' => $response];
|
||||
} else {
|
||||
// Response is an object or associative array, keep as is
|
||||
$combinedResponse["IDX_{$index}"] = $response;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// Log error and continue with other URLs
|
||||
Log::warning("Failed to fetch data from URL {$resolvedUrl}: ".$e->getMessage());
|
||||
Log::warning("Failed to fetch data from URL {$url}: ".$e->getMessage());
|
||||
$combinedResponse["IDX_{$index}"] = ['error' => 'Failed to fetch data'];
|
||||
}
|
||||
}
|
||||
|
||||
// unwrap IDX_0 if only one URL
|
||||
$finalPayload = (count($urls) === 1) ? reset($combinedResponse) : $combinedResponse;
|
||||
|
||||
$this->update([
|
||||
'data_payload' => $combinedResponse,
|
||||
'data_payload' => $finalPayload,
|
||||
'data_payload_updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function parseResponse(Response $httpResponse): array
|
||||
{
|
||||
|
|
|
|||
|
|
@ -99,6 +99,35 @@ test('updateDataPayload handles multiple URLs with IDX_ prefixes', function ():
|
|||
expect($plugin->data_payload['IDX_2'])->toBe(['headline' => 'test']);
|
||||
});
|
||||
|
||||
test('updateDataPayload skips empty lines in polling_url and maintains sequential IDX keys', function (): void {
|
||||
$plugin = Plugin::factory()->create([
|
||||
'data_strategy' => 'polling',
|
||||
// empty lines and extra spaces between the URL to generate empty entries
|
||||
'polling_url' => "https://api1.example.com/data\n \n\nhttps://api2.example.com/weather\n ",
|
||||
'polling_verb' => 'get',
|
||||
]);
|
||||
|
||||
// Mock only the valid URLs
|
||||
Http::fake([
|
||||
'https://api1.example.com/data' => Http::response(['item' => 'first'], 200),
|
||||
'https://api2.example.com/weather' => Http::response(['item' => 'second'], 200),
|
||||
]);
|
||||
|
||||
$plugin->updateDataPayload();
|
||||
|
||||
// payload should only have 2 items, and they should be indexed 0 and 1
|
||||
expect($plugin->data_payload)->toHaveCount(2);
|
||||
expect($plugin->data_payload)->toHaveKey('IDX_0');
|
||||
expect($plugin->data_payload)->toHaveKey('IDX_1');
|
||||
|
||||
// data is correct
|
||||
expect($plugin->data_payload['IDX_0'])->toBe(['item' => 'first']);
|
||||
expect($plugin->data_payload['IDX_1'])->toBe(['item' => 'second']);
|
||||
|
||||
// no empty index exists
|
||||
expect($plugin->data_payload)->not->toHaveKey('IDX_2');
|
||||
});
|
||||
|
||||
test('updateDataPayload handles single URL without nesting', function (): void {
|
||||
$plugin = Plugin::factory()->create([
|
||||
'data_strategy' => 'polling',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue