feat(uptelligence): add AltumCode vendor update checks
Add automated version checking for AltumCode products and plugins: - isAltumPlatform() routes altum vendors before OSS checks - checkAltumProduct() fetches latest_release_version from product info.php - checkAltumPlugin() looks up plugin versions from dev.altumcode.com - In-memory cache avoids redundant HTTP calls for multiple plugins 14 Pest tests covering all paths (43 assertions). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
cc1918b511
commit
f0a2f3fd1a
2 changed files with 496 additions and 2 deletions
|
|
@ -6,6 +6,8 @@ namespace Core\Mod\Uptelligence\Services;
|
||||||
|
|
||||||
use Core\Mod\Uptelligence\Models\UpstreamTodo;
|
use Core\Mod\Uptelligence\Models\UpstreamTodo;
|
||||||
use Core\Mod\Uptelligence\Models\Vendor;
|
use Core\Mod\Uptelligence\Models\Vendor;
|
||||||
|
use Illuminate\Http\Client\ConnectionException;
|
||||||
|
use Illuminate\Http\Client\RequestException;
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\Support\Facades\RateLimiter;
|
use Illuminate\Support\Facades\RateLimiter;
|
||||||
|
|
@ -17,6 +19,13 @@ use Illuminate\Support\Facades\RateLimiter;
|
||||||
*/
|
*/
|
||||||
class VendorUpdateCheckerService
|
class VendorUpdateCheckerService
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* In-memory cache for AltumCode plugin versions.
|
||||||
|
*
|
||||||
|
* Avoids redundant HTTP calls when checking multiple plugins in one run.
|
||||||
|
*/
|
||||||
|
protected ?array $altumPluginVersionsCache = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check all active vendors for updates.
|
* Check all active vendors for updates.
|
||||||
*
|
*
|
||||||
|
|
@ -42,6 +51,8 @@ class VendorUpdateCheckerService
|
||||||
{
|
{
|
||||||
// Determine check method based on source type and git URL
|
// Determine check method based on source type and git URL
|
||||||
$result = match (true) {
|
$result = match (true) {
|
||||||
|
$this->isAltumPlatform($vendor) && $vendor->isLicensed() => $this->checkAltumProduct($vendor),
|
||||||
|
$this->isAltumPlatform($vendor) && $vendor->isPlugin() => $this->checkAltumPlugin($vendor),
|
||||||
$vendor->isOss() && $this->isGitHubUrl($vendor->git_repo_url) => $this->checkGitHub($vendor),
|
$vendor->isOss() && $this->isGitHubUrl($vendor->git_repo_url) => $this->checkGitHub($vendor),
|
||||||
$vendor->isOss() && $this->isGiteaUrl($vendor->git_repo_url) => $this->checkGitea($vendor),
|
$vendor->isOss() && $this->isGiteaUrl($vendor->git_repo_url) => $this->checkGitea($vendor),
|
||||||
default => $this->skipCheck($vendor),
|
default => $this->skipCheck($vendor),
|
||||||
|
|
@ -89,10 +100,10 @@ class VendorUpdateCheckerService
|
||||||
->retry(3, function (int $attempt) {
|
->retry(3, function (int $attempt) {
|
||||||
return (int) pow(2, $attempt - 1) * 1000;
|
return (int) pow(2, $attempt - 1) * 1000;
|
||||||
}, function (\Exception $exception) {
|
}, function (\Exception $exception) {
|
||||||
if ($exception instanceof \Illuminate\Http\Client\ConnectionException) {
|
if ($exception instanceof ConnectionException) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ($exception instanceof \Illuminate\Http\Client\RequestException) {
|
if ($exception instanceof RequestException) {
|
||||||
$status = $exception->response?->status();
|
$status = $exception->response?->status();
|
||||||
|
|
||||||
return $status >= 500 || $status === 429;
|
return $status >= 500 || $status === 429;
|
||||||
|
|
@ -273,6 +284,125 @@ class VendorUpdateCheckerService
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if vendor belongs to the AltumCode platform.
|
||||||
|
*/
|
||||||
|
protected function isAltumPlatform(Vendor $vendor): bool
|
||||||
|
{
|
||||||
|
return $vendor->plugin_platform === Vendor::PLATFORM_ALTUM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check an AltumCode licensed product for updates.
|
||||||
|
*
|
||||||
|
* Fetches the product's info.php endpoint (e.g. https://66analytics.com/info.php)
|
||||||
|
* and reads the latest_release_version from the JSON response.
|
||||||
|
*/
|
||||||
|
protected function checkAltumProduct(Vendor $vendor): array
|
||||||
|
{
|
||||||
|
$url = "https://{$vendor->slug}.com/info.php";
|
||||||
|
|
||||||
|
try {
|
||||||
|
$response = Http::timeout(5)->get($url);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::warning('Uptelligence: AltumCode product check failed', [
|
||||||
|
'vendor' => $vendor->slug,
|
||||||
|
'url' => $url,
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $this->errorResult("AltumCode product check failed: {$e->getMessage()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $response->successful()) {
|
||||||
|
Log::warning('Uptelligence: AltumCode product info request failed', [
|
||||||
|
'vendor' => $vendor->slug,
|
||||||
|
'status' => $response->status(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $this->errorResult("AltumCode product info error: {$response->status()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $response->json();
|
||||||
|
$latestVersion = $this->normaliseVersion($data['latest_release_version'] ?? '');
|
||||||
|
|
||||||
|
return $this->buildResult(
|
||||||
|
vendor: $vendor,
|
||||||
|
latestVersion: $latestVersion,
|
||||||
|
releaseInfo: [
|
||||||
|
'source' => 'altum_product',
|
||||||
|
'url' => $url,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check an AltumCode plugin for updates.
|
||||||
|
*
|
||||||
|
* Fetches the plugin versions endpoint and looks up the plugin by ID
|
||||||
|
* (stripping the 'altum-plugin-' prefix from the vendor slug).
|
||||||
|
*/
|
||||||
|
protected function checkAltumPlugin(Vendor $vendor): array
|
||||||
|
{
|
||||||
|
$versions = $this->getAltumPluginVersions();
|
||||||
|
|
||||||
|
if ($versions === null) {
|
||||||
|
return $this->errorResult('Failed to fetch AltumCode plugin versions');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strip 'altum-plugin-' prefix from slug to get the plugin ID
|
||||||
|
$pluginId = str_replace('altum-plugin-', '', $vendor->slug);
|
||||||
|
|
||||||
|
if (! isset($versions[$pluginId])) {
|
||||||
|
return $this->errorResult("Plugin '{$pluginId}' not found in AltumCode registry");
|
||||||
|
}
|
||||||
|
|
||||||
|
$latestVersion = $this->normaliseVersion($versions[$pluginId]['version'] ?? '');
|
||||||
|
|
||||||
|
return $this->buildResult(
|
||||||
|
vendor: $vendor,
|
||||||
|
latestVersion: $latestVersion,
|
||||||
|
releaseInfo: [
|
||||||
|
'source' => 'altum_plugin',
|
||||||
|
'plugin_id' => $pluginId,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch AltumCode plugin versions with in-memory caching.
|
||||||
|
*
|
||||||
|
* @return array<string, array{version: string}>|null
|
||||||
|
*/
|
||||||
|
protected function getAltumPluginVersions(): ?array
|
||||||
|
{
|
||||||
|
if ($this->altumPluginVersionsCache !== null) {
|
||||||
|
return $this->altumPluginVersionsCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$response = Http::timeout(5)->get('https://dev.altumcode.com/plugins-versions');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::warning('Uptelligence: AltumCode plugin versions fetch failed', [
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $response->successful()) {
|
||||||
|
Log::warning('Uptelligence: AltumCode plugin versions request failed', [
|
||||||
|
'status' => $response->status(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->altumPluginVersionsCache = $response->json() ?? [];
|
||||||
|
|
||||||
|
return $this->altumPluginVersionsCache;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Skip check for vendors that don't support auto-checking.
|
* Skip check for vendors that don't support auto-checking.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
364
tests/Unit/AltumCodeCheckerTest.php
Normal file
364
tests/Unit/AltumCodeCheckerTest.php
Normal file
|
|
@ -0,0 +1,364 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Core\Mod\Uptelligence\Models\Vendor;
|
||||||
|
use Core\Mod\Uptelligence\Services\VendorUpdateCheckerService;
|
||||||
|
use Illuminate\Support\Facades\Http;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
$this->service = new VendorUpdateCheckerService;
|
||||||
|
});
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// isAltumPlatform
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
it('identifies altum platform vendors', function () {
|
||||||
|
$vendor = new Vendor([
|
||||||
|
'slug' => '66analytics',
|
||||||
|
'plugin_platform' => Vendor::PLATFORM_ALTUM,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$method = new ReflectionMethod($this->service, 'isAltumPlatform');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
|
||||||
|
expect($method->invoke($this->service, $vendor))->toBeTrue();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejects non-altum platform vendors', function () {
|
||||||
|
$vendor = new Vendor([
|
||||||
|
'slug' => 'some-wp-plugin',
|
||||||
|
'plugin_platform' => Vendor::PLATFORM_WORDPRESS,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$method = new ReflectionMethod($this->service, 'isAltumPlatform');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
|
||||||
|
expect($method->invoke($this->service, $vendor))->toBeFalse();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejects vendors with no platform set', function () {
|
||||||
|
$vendor = new Vendor([
|
||||||
|
'slug' => 'some-oss',
|
||||||
|
'plugin_platform' => null,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$method = new ReflectionMethod($this->service, 'isAltumPlatform');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
|
||||||
|
expect($method->invoke($this->service, $vendor))->toBeFalse();
|
||||||
|
});
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// checkAltumProduct
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
it('fetches latest version from altum product info endpoint', function () {
|
||||||
|
Http::fake([
|
||||||
|
'https://66analytics.com/info.php' => Http::response([
|
||||||
|
'latest_release_version' => '42.0.0',
|
||||||
|
'product_name' => '66analytics',
|
||||||
|
], 200),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$vendor = new Vendor([
|
||||||
|
'slug' => '66analytics',
|
||||||
|
'name' => '66analytics',
|
||||||
|
'plugin_platform' => Vendor::PLATFORM_ALTUM,
|
||||||
|
'source_type' => Vendor::SOURCE_LICENSED,
|
||||||
|
'current_version' => '41.0.0',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$method = new ReflectionMethod($this->service, 'checkAltumProduct');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
|
||||||
|
$result = $method->invoke($this->service, $vendor);
|
||||||
|
|
||||||
|
expect($result)
|
||||||
|
->toBeArray()
|
||||||
|
->and($result['status'])->toBe('success')
|
||||||
|
->and($result['latest'])->toBe('42.0.0')
|
||||||
|
->and($result['has_update'])->toBeTrue()
|
||||||
|
->and($result['release_info']['source'])->toBe('altum_product');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('detects no update when product version is current', function () {
|
||||||
|
Http::fake([
|
||||||
|
'https://66biolinks.com/info.php' => Http::response([
|
||||||
|
'latest_release_version' => '39.0.0',
|
||||||
|
], 200),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$vendor = new Vendor([
|
||||||
|
'slug' => '66biolinks',
|
||||||
|
'name' => '66biolinks',
|
||||||
|
'plugin_platform' => Vendor::PLATFORM_ALTUM,
|
||||||
|
'source_type' => Vendor::SOURCE_LICENSED,
|
||||||
|
'current_version' => '39.0.0',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$method = new ReflectionMethod($this->service, 'checkAltumProduct');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
|
||||||
|
$result = $method->invoke($this->service, $vendor);
|
||||||
|
|
||||||
|
expect($result['status'])->toBe('success')
|
||||||
|
->and($result['has_update'])->toBeFalse()
|
||||||
|
->and($result['latest'])->toBe('39.0.0');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns error when altum product endpoint fails', function () {
|
||||||
|
Http::fake([
|
||||||
|
'https://66analytics.com/info.php' => Http::response('Server Error', 500),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$vendor = new Vendor([
|
||||||
|
'slug' => '66analytics',
|
||||||
|
'name' => '66analytics',
|
||||||
|
'plugin_platform' => Vendor::PLATFORM_ALTUM,
|
||||||
|
'source_type' => Vendor::SOURCE_LICENSED,
|
||||||
|
'current_version' => '40.0.0',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$method = new ReflectionMethod($this->service, 'checkAltumProduct');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
|
||||||
|
$result = $method->invoke($this->service, $vendor);
|
||||||
|
|
||||||
|
expect($result['status'])->toBe('error')
|
||||||
|
->and($result['message'])->toContain('500');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns error when altum product has no version in response', function () {
|
||||||
|
Http::fake([
|
||||||
|
'https://66pusher.com/info.php' => Http::response([
|
||||||
|
'product_name' => '66pusher',
|
||||||
|
// No latest_release_version key
|
||||||
|
], 200),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$vendor = new Vendor([
|
||||||
|
'slug' => '66pusher',
|
||||||
|
'name' => '66pusher',
|
||||||
|
'plugin_platform' => Vendor::PLATFORM_ALTUM,
|
||||||
|
'source_type' => Vendor::SOURCE_LICENSED,
|
||||||
|
'current_version' => '5.0.0',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$method = new ReflectionMethod($this->service, 'checkAltumProduct');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
|
||||||
|
$result = $method->invoke($this->service, $vendor);
|
||||||
|
|
||||||
|
expect($result['status'])->toBe('error')
|
||||||
|
->and($result['message'])->toContain('Could not determine latest version');
|
||||||
|
});
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// checkAltumPlugin
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
it('fetches latest version for an altum plugin', function () {
|
||||||
|
Http::fake([
|
||||||
|
'https://dev.altumcode.com/plugins-versions' => Http::response([
|
||||||
|
'affiliate' => ['version' => '2.0.1'],
|
||||||
|
'email-notifications' => ['version' => '3.1.0'],
|
||||||
|
], 200),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$vendor = new Vendor([
|
||||||
|
'slug' => 'altum-plugin-affiliate',
|
||||||
|
'name' => 'AltumCode Affiliate Plugin',
|
||||||
|
'plugin_platform' => Vendor::PLATFORM_ALTUM,
|
||||||
|
'source_type' => Vendor::SOURCE_PLUGIN,
|
||||||
|
'current_version' => '1.5.0',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$method = new ReflectionMethod($this->service, 'checkAltumPlugin');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
|
||||||
|
$result = $method->invoke($this->service, $vendor);
|
||||||
|
|
||||||
|
expect($result['status'])->toBe('success')
|
||||||
|
->and($result['latest'])->toBe('2.0.1')
|
||||||
|
->and($result['has_update'])->toBeTrue()
|
||||||
|
->and($result['release_info']['source'])->toBe('altum_plugin')
|
||||||
|
->and($result['release_info']['plugin_id'])->toBe('affiliate');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns error when plugin is not found in altum registry', function () {
|
||||||
|
Http::fake([
|
||||||
|
'https://dev.altumcode.com/plugins-versions' => Http::response([
|
||||||
|
'affiliate' => ['version' => '2.0.1'],
|
||||||
|
], 200),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$vendor = new Vendor([
|
||||||
|
'slug' => 'altum-plugin-nonexistent',
|
||||||
|
'name' => 'Nonexistent Plugin',
|
||||||
|
'plugin_platform' => Vendor::PLATFORM_ALTUM,
|
||||||
|
'source_type' => Vendor::SOURCE_PLUGIN,
|
||||||
|
'current_version' => '1.0.0',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$method = new ReflectionMethod($this->service, 'checkAltumPlugin');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
|
||||||
|
$result = $method->invoke($this->service, $vendor);
|
||||||
|
|
||||||
|
expect($result['status'])->toBe('error')
|
||||||
|
->and($result['message'])->toContain('nonexistent')
|
||||||
|
->and($result['message'])->toContain('not found');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns error when plugin versions endpoint fails', function () {
|
||||||
|
Http::fake([
|
||||||
|
'https://dev.altumcode.com/plugins-versions' => Http::response('Bad Gateway', 502),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$vendor = new Vendor([
|
||||||
|
'slug' => 'altum-plugin-affiliate',
|
||||||
|
'name' => 'AltumCode Affiliate Plugin',
|
||||||
|
'plugin_platform' => Vendor::PLATFORM_ALTUM,
|
||||||
|
'source_type' => Vendor::SOURCE_PLUGIN,
|
||||||
|
'current_version' => '1.0.0',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$method = new ReflectionMethod($this->service, 'checkAltumPlugin');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
|
||||||
|
$result = $method->invoke($this->service, $vendor);
|
||||||
|
|
||||||
|
expect($result['status'])->toBe('error')
|
||||||
|
->and($result['message'])->toContain('Failed to fetch');
|
||||||
|
});
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// In-memory cache
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
it('caches plugin versions across multiple calls', function () {
|
||||||
|
Http::fake([
|
||||||
|
'https://dev.altumcode.com/plugins-versions' => Http::response([
|
||||||
|
'affiliate' => ['version' => '2.0.1'],
|
||||||
|
'email-notifications' => ['version' => '3.1.0'],
|
||||||
|
], 200),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$method = new ReflectionMethod($this->service, 'getAltumPluginVersions');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
|
||||||
|
// First call — should hit the HTTP endpoint
|
||||||
|
$first = $method->invoke($this->service);
|
||||||
|
expect($first)->toBeArray()->toHaveKey('affiliate');
|
||||||
|
|
||||||
|
// Second call — should use cache (no additional HTTP request)
|
||||||
|
$second = $method->invoke($this->service);
|
||||||
|
expect($second)->toBe($first);
|
||||||
|
|
||||||
|
// Verify HTTP was only called once
|
||||||
|
Http::assertSentCount(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Match routing via checkVendor (integration-level)
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
it('routes altum licensed vendor through checkAltumProduct', function () {
|
||||||
|
Http::fake([
|
||||||
|
'https://66analytics.com/info.php' => Http::response([
|
||||||
|
'latest_release_version' => '42.0.0',
|
||||||
|
], 200),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$vendor = Mockery::mock(Vendor::class)->makePartial();
|
||||||
|
$vendor->shouldReceive('getAttribute')->with('slug')->andReturn('66analytics');
|
||||||
|
$vendor->shouldReceive('getAttribute')->with('name')->andReturn('66analytics');
|
||||||
|
$vendor->shouldReceive('getAttribute')->with('plugin_platform')->andReturn(Vendor::PLATFORM_ALTUM);
|
||||||
|
$vendor->shouldReceive('getAttribute')->with('source_type')->andReturn(Vendor::SOURCE_LICENSED);
|
||||||
|
$vendor->shouldReceive('getAttribute')->with('current_version')->andReturn('41.0.0');
|
||||||
|
$vendor->shouldReceive('getAttribute')->with('git_repo_url')->andReturn(null);
|
||||||
|
$vendor->shouldReceive('update')->once()->with(Mockery::on(function ($data) {
|
||||||
|
return array_key_exists('last_checked_at', $data);
|
||||||
|
}));
|
||||||
|
$vendor->shouldReceive('isLicensed')->andReturn(true);
|
||||||
|
$vendor->shouldReceive('isPlugin')->andReturn(false);
|
||||||
|
$vendor->shouldReceive('isOss')->andReturn(false);
|
||||||
|
|
||||||
|
// Use a partial mock of the service to prevent createUpdateTodo from hitting DB
|
||||||
|
$service = Mockery::mock(VendorUpdateCheckerService::class)->makePartial();
|
||||||
|
$service->shouldAllowMockingProtectedMethods();
|
||||||
|
$service->shouldReceive('createUpdateTodo')->once();
|
||||||
|
|
||||||
|
$result = $service->checkVendor($vendor);
|
||||||
|
|
||||||
|
expect($result['status'])->toBe('success')
|
||||||
|
->and($result['latest'])->toBe('42.0.0')
|
||||||
|
->and($result['has_update'])->toBeTrue();
|
||||||
|
|
||||||
|
Http::assertSent(function ($request) {
|
||||||
|
return $request->url() === 'https://66analytics.com/info.php';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('routes altum plugin vendor through checkAltumPlugin', function () {
|
||||||
|
Http::fake([
|
||||||
|
'https://dev.altumcode.com/plugins-versions' => Http::response([
|
||||||
|
'affiliate' => ['version' => '2.0.1'],
|
||||||
|
], 200),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$vendor = Mockery::mock(Vendor::class)->makePartial();
|
||||||
|
$vendor->shouldReceive('getAttribute')->with('slug')->andReturn('altum-plugin-affiliate');
|
||||||
|
$vendor->shouldReceive('getAttribute')->with('name')->andReturn('Affiliate Plugin');
|
||||||
|
$vendor->shouldReceive('getAttribute')->with('plugin_platform')->andReturn(Vendor::PLATFORM_ALTUM);
|
||||||
|
$vendor->shouldReceive('getAttribute')->with('source_type')->andReturn(Vendor::SOURCE_PLUGIN);
|
||||||
|
$vendor->shouldReceive('getAttribute')->with('current_version')->andReturn('1.5.0');
|
||||||
|
$vendor->shouldReceive('getAttribute')->with('git_repo_url')->andReturn(null);
|
||||||
|
$vendor->shouldReceive('update')->once()->with(Mockery::on(function ($data) {
|
||||||
|
return array_key_exists('last_checked_at', $data);
|
||||||
|
}));
|
||||||
|
$vendor->shouldReceive('isLicensed')->andReturn(false);
|
||||||
|
$vendor->shouldReceive('isPlugin')->andReturn(true);
|
||||||
|
$vendor->shouldReceive('isOss')->andReturn(false);
|
||||||
|
|
||||||
|
// Use a partial mock of the service to prevent createUpdateTodo from hitting DB
|
||||||
|
$service = Mockery::mock(VendorUpdateCheckerService::class)->makePartial();
|
||||||
|
$service->shouldAllowMockingProtectedMethods();
|
||||||
|
$service->shouldReceive('createUpdateTodo')->once();
|
||||||
|
|
||||||
|
$result = $service->checkVendor($vendor);
|
||||||
|
|
||||||
|
expect($result['status'])->toBe('success')
|
||||||
|
->and($result['latest'])->toBe('2.0.1')
|
||||||
|
->and($result['has_update'])->toBeTrue();
|
||||||
|
|
||||||
|
Http::assertSent(function ($request) {
|
||||||
|
return $request->url() === 'https://dev.altumcode.com/plugins-versions';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('normalises version with v prefix from altum product', function () {
|
||||||
|
Http::fake([
|
||||||
|
'https://66socialproof.com/info.php' => Http::response([
|
||||||
|
'latest_release_version' => 'v7.0.0',
|
||||||
|
], 200),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$vendor = new Vendor([
|
||||||
|
'slug' => '66socialproof',
|
||||||
|
'name' => '66socialproof',
|
||||||
|
'plugin_platform' => Vendor::PLATFORM_ALTUM,
|
||||||
|
'source_type' => Vendor::SOURCE_LICENSED,
|
||||||
|
'current_version' => '6.0.0',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$method = new ReflectionMethod($this->service, 'checkAltumProduct');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
|
||||||
|
$result = $method->invoke($this->service, $vendor);
|
||||||
|
|
||||||
|
expect($result['latest'])->toBe('7.0.0')
|
||||||
|
->and($result['has_update'])->toBeTrue();
|
||||||
|
});
|
||||||
Loading…
Add table
Reference in a new issue