Skip to content

Commit

Permalink
Fix missing H5P content type icons caused by h5p-editor library downg…
Browse files Browse the repository at this point in the history
…rade. Add tests
  • Loading branch information
chrieinv committed Oct 12, 2023
1 parent e05361b commit 3bea69f
Show file tree
Hide file tree
Showing 6 changed files with 245 additions and 4 deletions.
3 changes: 3 additions & 0 deletions sourcecode/apis/contentauthor/app/H5PLibrariesHubCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

Expand All @@ -16,6 +17,8 @@

class H5PLibrariesHubCache extends Model
{
use HasFactory;

protected $table = 'h5p_libraries_hub_cache';

protected $guarded = [];
Expand Down
3 changes: 3 additions & 0 deletions sourcecode/apis/contentauthor/app/H5PLibraryCapability.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
namespace App;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Facades\Lang;

class H5PLibraryCapability extends Model
{
use HasFactory;

protected $table = 'h5p_library_capabilities';

protected $appends = ['title', 'description'];
Expand Down
8 changes: 4 additions & 4 deletions sourcecode/apis/contentauthor/composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

namespace Database\Factories;

use App\H5PLibrariesHubCache;
use Illuminate\Database\Eloquent\Factories\Factory;

/**
* @template-extends Factory<H5PLibrariesHubCache>
*/
class H5PLibrariesHubCacheFactory extends Factory
{
public function definition(): array
{
return [
'name' => 'H5P.Foobar',
'major_version' => 2,
'minor_version' => 4,
'patch_version' => 6,
'h5p_major_version' => 1,
'h5p_minor_version' => 25,
'title' => $this->faker->words(3, true),
'summary' => $this->faker->sentence,
'description' => $this->faker->sentences(3, true),
'icon' => $this->faker->url . '/icon.svg',
'is_recommended' => 0,
'popularity' => $this->faker->numberBetween(0, 100000),
'screenshots' => json_encode([
$this->faker->url . '/image01.jpg',
$this->faker->url . '/image02.jpg',
$this->faker->url . '/image03.jpg',
]),
'license' => '{"id":"MIT","attributes":{"useCommercially":true,"modifiable":true,"distributable":true,"sublicensable":true,"canHoldLiable":false,"mustIncludeCopyright":true,"mustIncludeLicense":true}}',
'example' => $this->faker->url,
'tutorial' => $this->faker->url,
'keywords' => json_encode($this->faker->words()),
'categories' => '["Other"]',
'owner' => $this->faker->userName,
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace Database\Factories;

use App\H5PLibraryCapability;
use Illuminate\Database\Eloquent\Factories\Factory;

/**
* @template-extends Factory<H5PLibraryCapability>
*/
class H5PLibraryCapabilityFactory extends Factory
{
public function definition(): array
{
return [
'library_id' => $this->faker->numberBetween(),
'name' => 'H5P.Foobar 1.2',
'score' => 0,
'enabled' => 1,
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@

namespace Tests\Integration\Libraries\H5P;

use App\H5PLibrariesHubCache;
use App\H5PLibrary;
use App\H5PLibraryCapability;
use App\Libraries\H5P\AjaxRequest;
use Generator;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Storage;
use Tests\TestCase;

class AjaxRequestTest extends TestCase
Expand Down Expand Up @@ -61,4 +65,168 @@ public function test_libraryRebuild(): void
'dependency_type' => 'editor',
]);
}

/** @dataProvider provider_contentTypeCache_icon */
public function test_contentTypeCache_icon(array $libraryData, string $iconPath): void
{
Storage::fake('test');

$library = H5PLibrary::factory()->create($libraryData);

H5PLibraryCapability::factory()->create([
'library_id' => $library->id,
]);

if ($iconPath !== '') {
Storage::put($iconPath, 'icon content');
}

$content = $this
->post('/ajax', ['action' => \H5PEditorEndpoints::CONTENT_TYPE_CACHE, 'h5p_id' => ''])
->assertOk()
->assertJsonStructure([
'outdated',
'libraries',
'recentlyUsed',
'apiVersion' => [
'major',
'minor',
],
'details',
])
->decodeResponseJson();

$libraries = $content['libraries'];
$this->assertCount(1, $libraries);
$libData = $libraries[0];

$this->assertSame($library->name, $libData['machineName']);

if ($library->has_icon) {
$this->assertStringContainsString($iconPath, $libData['icon']);
} else {
$this->assertArrayNotHasKey('icon', $libData);
}
}

public function provider_contentTypeCache_icon(): Generator
{
yield 'No patch with icon' => [
[
'has_icon' => true,
'patch_version_in_folder_name' => false,
],
'libraries/H5P.Foobar-1.2/icon.svg',
];

yield 'Patch with icon' => [
[
'has_icon' => true,
'patch_version_in_folder_name' => true,
],
'libraries/H5P.Foobar-1.2.3/icon.svg',
];

yield 'Missing icon' => [
[
'has_icon' => true,
'patch_version_in_folder_name' => true,
],
'',
];

yield 'No icon' => [
[
'has_icon' => false,
'patch_version_in_folder_name' => true,
],
'libraries/H5P.Foobar-1.2.3/icon.svg',
];
}

/** @dataProvider provider_contentTypeCache_LocalAndCache */
public function test_contentTypeCache_localAndCache(bool $usePatchVersion): void
{
Storage::fake('test');

$localOnlyLibrary = H5PLibrary::factory()->create([
'name' => 'H5P.Snafu',
'has_icon' => true,
'patch_version_in_folder_name' => $usePatchVersion,
]);
H5PLibraryCapability::factory()->create([
'library_id' => $localOnlyLibrary->id,
]);

$library = H5PLibrary::factory()->create([
'patch_version_in_folder_name' => $usePatchVersion,
]);
H5PLibraryCapability::factory()->create([
'library_id' => $library->id,
]);

$hubLibrary = H5PLibrariesHubCache::factory()->create();

$content = $this
->withSession(['isAdmin' => true])
->post('/ajax', ['action' => \H5PEditorEndpoints::CONTENT_TYPE_CACHE, 'h5p_id' => ''])
->assertOk()
->assertJsonStructure([
'outdated',
'libraries',
'recentlyUsed',
'apiVersion' => [
'major',
'minor',
],
'details',
])
->decodeResponseJson();

$this->assertCount(2, $content['libraries']);

$libData = $content['libraries'][0];
$this->assertSame($hubLibrary->id, $libData['id']);
$this->assertSame($hubLibrary->title, $libData['title']);
$this->assertSame($hubLibrary->major_version, $libData['majorVersion']);
$this->assertSame($hubLibrary->minor_version, $libData['minorVersion']);
$this->assertSame($hubLibrary->patch_version, $libData['patchVersion']);
$this->assertSame($library->major_version, $libData['localMajorVersion']);
$this->assertSame($library->minor_version, $libData['localMinorVersion']);
$this->assertSame($library->patch_version, $libData['localPatchVersion']);
$this->assertTrue($libData['installed']);
$this->assertFalse($libData['isUpToDate']);
$this->assertFalse($libData['restricted']);
$this->assertFalse($libData['canInstall']);
$this->assertArrayHasKey('summary', $libData);
$this->assertArrayHasKey('isRecommended', $libData);
$this->assertArrayHasKey('popularity', $libData);
$this->assertArrayHasKey('screenshots', $libData);
$this->assertArrayHasKey('license', $libData);

$libData = $content['libraries'][1];
$this->assertSame($localOnlyLibrary->id, $libData['id']);
$this->assertSame($localOnlyLibrary->title, $libData['title']);
$this->assertSame($localOnlyLibrary->major_version, $libData['majorVersion']);
$this->assertSame($localOnlyLibrary->minor_version, $libData['minorVersion']);
$this->assertSame($localOnlyLibrary->patch_version, $libData['patchVersion']);
$this->assertSame($localOnlyLibrary->major_version, $libData['localMajorVersion']);
$this->assertSame($localOnlyLibrary->minor_version, $libData['localMinorVersion']);
$this->assertSame($localOnlyLibrary->patch_version, $libData['localPatchVersion']);
$this->assertTrue($libData['installed']);
$this->assertTrue($libData['isUpToDate']);
$this->assertFalse($libData['restricted']);
$this->assertFalse($libData['canInstall']);
$this->assertArrayNotHasKey('summary', $libData);
$this->assertArrayNotHasKey('isRecommended', $libData);
$this->assertArrayNotHasKey('popularity', $libData);
$this->assertArrayNotHasKey('screenshots', $libData);
$this->assertArrayNotHasKey('license', $libData);
}

public function provider_contentTypeCache_localAndCache(): Generator
{
yield 'no patch version' => [false];
yield 'patch version' => [true];
}
}

0 comments on commit 3bea69f

Please sign in to comment.