mirror of
https://gh.wpcy.net/https://github.com/fairpm/aspirecloud.git
synced 2026-06-20 02:22:28 +08:00
374 lines
14 KiB
PHP
374 lines
14 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
use App\Models\WpOrg\Author;
|
|
use App\Models\WpOrg\Theme;
|
|
use Carbon\CarbonImmutable;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
beforeEach(function () {
|
|
$author = Author::create([
|
|
'user_nicename' => 'tmeister',
|
|
'profile' => 'https://profiles.wp.org/tmeister',
|
|
'avatar' => 'https://avatars.wp.org/tmeister',
|
|
'display_name' => 'Tmeister',
|
|
'author' => 'Tmeister',
|
|
'author_url' => 'https://wp-themes.com/author/tmeister',
|
|
]);
|
|
|
|
Theme::factory()->create([
|
|
'ac_origin' => 'wp_org',
|
|
'active_installs' => 100,
|
|
'author_id' => $author->id,
|
|
'creation_time' => CarbonImmutable::parse('2011-11-11 11:11:11'),
|
|
'description' => 'My Theme',
|
|
'download_link' => 'https://downloads.wp/my-theme',
|
|
'downloaded' => 1000,
|
|
'external_repository_url' => 'https://test.com',
|
|
'homepage' => 'https://wordpress.org/themes/my-theme/',
|
|
'is_commercial' => false,
|
|
'is_community' => true,
|
|
'last_updated' => '2025-01-18T20:50:36+00:00',
|
|
'name' => 'My Theme',
|
|
'num_ratings' => 6,
|
|
'preview_url' => 'https://wp-themes.com/my-theme',
|
|
'rating' => 5,
|
|
'reviews_url' => 'https://wp-themes.com/my-theme/reviews',
|
|
'requires_php' => '5.6',
|
|
'screenshot_url' => 'https://wp-themes.com/my-theme/screenshot.png',
|
|
'slug' => 'my-theme',
|
|
'version' => '1.2.1',
|
|
])->addTagsBySlugs(['black', 'white', 'red', 'blue']);
|
|
});
|
|
|
|
it('returns 400 when slug is missing', function () {
|
|
$response = $this->get('/themes/info/1.2?action=theme_information');
|
|
|
|
$response
|
|
->assertStatus(400)
|
|
->assertJson(['error' => 'The slug field is required.']);
|
|
});
|
|
|
|
it('returns 404 when theme does not exist', function () {
|
|
$response = $this->get('/themes/info/1.2?action=theme_information&slug=non-existent-theme');
|
|
|
|
$response
|
|
->assertStatus(404)
|
|
->assertJson(['error' => 'Theme not found']);
|
|
});
|
|
|
|
it('returns theme_information (v1.1)', function () {
|
|
$response = $this->get('/themes/info/1.1?action=theme_information&slug=my-theme');
|
|
|
|
$response
|
|
->assertStatus(200)
|
|
->assertJson([
|
|
'author' => 'tmeister',
|
|
'download_link' => 'https://api.aspiredev.org/download/my-theme',
|
|
'downloaded' => 1000,
|
|
'homepage' => 'https://wordpress.org/themes/my-theme/',
|
|
'last_updated' => '2025-01-18',
|
|
'last_updated_time' => '2025-01-18 20:50:36',
|
|
'name' => 'My Theme',
|
|
'num_ratings' => 6,
|
|
'preview_url' => 'https://wp-themes.com/my-theme',
|
|
'rating' => 5,
|
|
'screenshot_url' => 'https://wp-themes.com/my-theme/screenshot.png',
|
|
'sections' => [],
|
|
'slug' => 'my-theme',
|
|
'tags' => [
|
|
'black' => 'black',
|
|
'blue' => 'blue',
|
|
'red' => 'red',
|
|
'white' => 'white',
|
|
],
|
|
'version' => '1.2.1',
|
|
]);
|
|
});
|
|
|
|
it('returns all fields in theme_information (v1.2)', function () {
|
|
$response = $this->get('/themes/info/1.2?action=theme_information&slug=my-theme');
|
|
|
|
$response
|
|
->assertStatus(200)
|
|
->assertJson([
|
|
'author' => [
|
|
'author' => 'Tmeister',
|
|
'author_url' => 'https://wp-themes.com/author/tmeister',
|
|
'avatar' => 'https://avatars.wp.org/tmeister',
|
|
'display_name' => 'Tmeister',
|
|
'profile' => 'https://profiles.wp.org/tmeister',
|
|
'user_nicename' => 'tmeister',
|
|
],
|
|
'creation_time' => '2011-11-11 11:11:11',
|
|
'download_link' => 'https://api.aspiredev.org/download/my-theme',
|
|
'downloaded' => 1000,
|
|
'external_repository_url' => 'https://test.com',
|
|
'homepage' => 'https://wordpress.org/themes/my-theme/',
|
|
'is_commercial' => false,
|
|
'is_community' => true,
|
|
'last_updated' => '2025-01-18',
|
|
'last_updated_time' => '2025-01-18 20:50:36',
|
|
'name' => 'My Theme',
|
|
'num_ratings' => 6,
|
|
'preview_url' => 'https://wp-themes.com/my-theme',
|
|
'rating' => 5,
|
|
'requires_php' => '5.6',
|
|
'reviews_url' => 'https://wp-themes.com/my-theme/reviews',
|
|
'screenshot_url' => 'https://wp-themes.com/my-theme/screenshot.png',
|
|
'sections' => [],
|
|
'slug' => 'my-theme',
|
|
'tags' => [
|
|
'black' => 'black',
|
|
'blue' => 'blue',
|
|
'red' => 'red',
|
|
'white' => 'white',
|
|
],
|
|
'version' => '1.2.1',
|
|
]);
|
|
});
|
|
|
|
it('returns theme query results (v1.1)', function () {
|
|
$this
|
|
->get('/themes/info/1.1?action=query_themes')
|
|
->assertStatus(200)
|
|
->assertJson([
|
|
'info' => ['page' => 1, 'pages' => 1, 'results' => 1],
|
|
'themes' => [
|
|
[
|
|
'author' => 'tmeister',
|
|
'description' => 'My Theme',
|
|
'homepage' => 'https://wordpress.org/themes/my-theme/',
|
|
'name' => 'My Theme',
|
|
'num_ratings' => 6,
|
|
'preview_url' => 'https://wp-themes.com/my-theme',
|
|
'rating' => 5,
|
|
'screenshot_url' => 'https://wp-themes.com/my-theme/screenshot.png',
|
|
'slug' => 'my-theme',
|
|
'version' => '1.2.1',
|
|
],
|
|
],
|
|
]);
|
|
});
|
|
|
|
it('returns theme query results (v1.2)', function () {
|
|
$this
|
|
->get('/themes/info/1.2?action=query_themes')
|
|
->assertStatus(200)
|
|
->assertJson([
|
|
'info' => ['page' => 1, 'pages' => 1, 'results' => 1],
|
|
'themes' => [
|
|
[
|
|
'author' => [
|
|
'author' => 'Tmeister',
|
|
'author_url' => 'https://wp-themes.com/author/tmeister',
|
|
'avatar' => 'https://avatars.wp.org/tmeister',
|
|
'display_name' => 'Tmeister',
|
|
'profile' => 'https://profiles.wp.org/tmeister',
|
|
'user_nicename' => 'tmeister',
|
|
],
|
|
'description' => 'My Theme',
|
|
'external_repository_url' => 'https://test.com',
|
|
'homepage' => 'https://wordpress.org/themes/my-theme/',
|
|
'is_commercial' => false,
|
|
'is_community' => true,
|
|
'name' => 'My Theme',
|
|
'num_ratings' => 6,
|
|
'preview_url' => 'https://wp-themes.com/my-theme',
|
|
'rating' => 5,
|
|
'requires_php' => '5.6',
|
|
'screenshot_url' => 'https://wp-themes.com/my-theme/screenshot.png',
|
|
'slug' => 'my-theme',
|
|
'version' => '1.2.1',
|
|
],
|
|
],
|
|
])
|
|
// GH-278: return all fields. these are not normally returned by default by .org
|
|
->assertJsonPath('themes.0.download_link', 'https://api.aspiredev.org/download/my-theme')
|
|
->assertJsonPath('themes.0.downloaded', 1000)
|
|
->assertJsonPath('themes.0.active_installs', 100)
|
|
->assertJsonPath('themes.0.tags.black', 'black');
|
|
});
|
|
|
|
it('returns theme query results for tags (v1.2)', function () {
|
|
$this
|
|
->get('/themes/info/1.2?action=query_themes&tag[]=black&tag[]=orange')
|
|
->assertStatus(200)
|
|
->assertJson([
|
|
'info' => ['page' => 1, 'pages' => 1, 'results' => 1],
|
|
'themes' => [
|
|
[
|
|
'author' => [
|
|
'author' => 'Tmeister',
|
|
'author_url' => 'https://wp-themes.com/author/tmeister',
|
|
'avatar' => 'https://avatars.wp.org/tmeister',
|
|
'display_name' => 'Tmeister',
|
|
'profile' => 'https://profiles.wp.org/tmeister',
|
|
'user_nicename' => 'tmeister',
|
|
],
|
|
'description' => 'My Theme',
|
|
'external_repository_url' => 'https://test.com',
|
|
'homepage' => 'https://wordpress.org/themes/my-theme/',
|
|
'is_commercial' => false,
|
|
'is_community' => true,
|
|
'name' => 'My Theme',
|
|
'num_ratings' => 6,
|
|
'preview_url' => 'https://wp-themes.com/my-theme',
|
|
'rating' => 5,
|
|
'requires_php' => '5.6',
|
|
'screenshot_url' => 'https://wp-themes.com/my-theme/screenshot.png',
|
|
'slug' => 'my-theme',
|
|
'version' => '1.2.1',
|
|
],
|
|
],
|
|
]);
|
|
|
|
$this
|
|
->get('/themes/info/1.2?action=query_themes&tag=orange')
|
|
->assertStatus(200)
|
|
->assertExactJson([
|
|
'info' => ['page' => 1, 'pages' => 0, 'results' => 0], // page 1 of 0 is a bit odd but it is correct
|
|
'themes' => [],
|
|
]);
|
|
});
|
|
|
|
it('returns theme query results for ac_tags (v1.2)', function () {
|
|
$this
|
|
->get('/themes/info/1.2?action=query_themes&ac_tag[]=black&ac_tag[]=blue')
|
|
->assertStatus(200)
|
|
->assertJson([
|
|
'info' => ['page' => 1, 'pages' => 1, 'results' => 1],
|
|
'themes' => [
|
|
[
|
|
'author' => [
|
|
'author' => 'Tmeister',
|
|
'author_url' => 'https://wp-themes.com/author/tmeister',
|
|
'avatar' => 'https://avatars.wp.org/tmeister',
|
|
'display_name' => 'Tmeister',
|
|
'profile' => 'https://profiles.wp.org/tmeister',
|
|
'user_nicename' => 'tmeister',
|
|
],
|
|
'description' => 'My Theme',
|
|
'external_repository_url' => 'https://test.com',
|
|
'homepage' => 'https://wordpress.org/themes/my-theme/',
|
|
'is_commercial' => false,
|
|
'is_community' => true,
|
|
'name' => 'My Theme',
|
|
'num_ratings' => 6,
|
|
'preview_url' => 'https://wp-themes.com/my-theme',
|
|
'rating' => 5,
|
|
'requires_php' => '5.6',
|
|
'screenshot_url' => 'https://wp-themes.com/my-theme/screenshot.png',
|
|
'slug' => 'my-theme',
|
|
'version' => '1.2.1',
|
|
],
|
|
],
|
|
]);
|
|
|
|
$this
|
|
->get('/themes/info/1.2?action=query_themes&tag=orange')
|
|
->assertStatus(200)
|
|
->assertExactJson([
|
|
'info' => ['page' => 1, 'pages' => 0, 'results' => 0], // page 1 of 0 is a bit odd but it is correct
|
|
'themes' => [],
|
|
]);
|
|
});
|
|
|
|
it('ANDs together ac_tags (v1.2)', function () {
|
|
$this
|
|
->get('/themes/info/1.2?action=query_themes&ac_tag[]=black&ac_tag[]=orange')
|
|
->assertStatus(200)
|
|
->assertJson([
|
|
'info' => ['page' => 1, 'pages' => 0, 'results' => 0],
|
|
'themes' => [],
|
|
]);
|
|
|
|
$this
|
|
->get('/themes/info/1.2?action=query_themes&tag=orange')
|
|
->assertStatus(200)
|
|
->assertExactJson([
|
|
'info' => ['page' => 1, 'pages' => 0, 'results' => 0], // page 1 of 0 is a bit odd but it is correct
|
|
'themes' => [],
|
|
]);
|
|
});
|
|
|
|
it('returns hot tags results (v1.1)', function () {
|
|
$this
|
|
->get('/themes/info/1.1?action=hot_tags')
|
|
->assertStatus(200)
|
|
->assertExactJson([
|
|
'black' => ['count' => 1, 'name' => 'black', 'slug' => 'black'],
|
|
'blue' => ['count' => 1, 'name' => 'blue', 'slug' => 'blue'],
|
|
'red' => ['count' => 1, 'name' => 'red', 'slug' => 'red'],
|
|
'white' => ['count' => 1, 'name' => 'white', 'slug' => 'white'],
|
|
]);
|
|
// TODO: test the actual hot tags sorting algorithm with multiple plugins
|
|
});
|
|
|
|
it('returns latest feature list when no wp version given (v1.2)', function () {
|
|
$this
|
|
->get('/themes/info/1.2?action=feature_list')
|
|
->assertStatus(200)
|
|
->assertExactJsonStructure(['Features', 'Layout', 'Subject'])
|
|
->assertJsonCount(26, 'Features')
|
|
->assertJsonCount(8, 'Layout')
|
|
->assertJsonCount(9, 'Subject');
|
|
});
|
|
|
|
it('returns feature list for wp version < 3.7.999 (v1.2)', function () {
|
|
$this
|
|
->get('/themes/info/1.2?action=feature_list&wp_version=3.7.998')
|
|
->assertStatus(200)
|
|
->assertExactJsonStructure(['Colors', 'Columns', 'Features', 'Subject', 'Width'])
|
|
->assertJsonCount(15, 'Colors')
|
|
->assertJsonCount(6, 'Columns')
|
|
->assertJsonCount(19, 'Features')
|
|
->assertJsonCount(3, 'Subject')
|
|
->assertJsonCount(2, 'Width');
|
|
});
|
|
|
|
it('returns latest feature list when no user-agent set (v1.1)', function () {
|
|
$this
|
|
->get('/themes/info/1.1?action=feature_list')
|
|
->assertStatus(200)
|
|
->assertExactJsonStructure(['Features', 'Layout', 'Subject'])
|
|
->assertJsonCount(26, 'Features')
|
|
->assertJsonCount(8, 'Layout')
|
|
->assertJsonCount(9, 'Subject');
|
|
});
|
|
|
|
// perverse, but something should test it
|
|
it('returns latest feature list in serialized object format (v1.0)', function () {
|
|
$body = $this
|
|
->get('/themes/info/1.0?action=feature_list')
|
|
->assertStatus(200)
|
|
->content();
|
|
|
|
$response = unserialize($body);
|
|
expect($response)->toBeObject();
|
|
expect($response)->toHaveProperty('Features');
|
|
expect($response)->toHaveProperty('Layout');
|
|
expect($response)->toHaveProperty('Subject');
|
|
expect($response->Features)->toBeArray()->toHaveCount(26);
|
|
expect($response->Layout)->toBeArray()->toHaveCount(8);
|
|
expect($response->Subject)->toBeArray()->toHaveCount(9);
|
|
});
|
|
|
|
it('returns feature list for wp version < 3.7.999 (v1.1)', function () {
|
|
$this
|
|
->withHeader('User-Agent', 'WordPress/3.7.998')
|
|
->get('/themes/info/1.1?action=feature_list')
|
|
->assertStatus(200)
|
|
->assertExactJsonStructure(['Colors', 'Columns', 'Features', 'Subject', 'Width'])
|
|
->assertJsonCount(15, 'Colors')
|
|
->assertJsonCount(6, 'Columns')
|
|
->assertJsonCount(19, 'Features')
|
|
->assertJsonCount(3, 'Subject')
|
|
->assertJsonCount(2, 'Width');
|
|
});
|
|
|
|
it('rejects invalid action with 404 not found', function () {
|
|
$response = $this->get('/themes/info/1.2?action=bogus')->assertNotFound();
|
|
});
|