fix(smart-playlist): ignore songs when creating a smart playlist (#1362)

This commit is contained in:
Phan An 2021-10-08 12:19:44 +02:00 committed by GitHub
parent 66badd0098
commit 230ec454dd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 94 additions and 9 deletions

View file

@ -1,8 +1,10 @@
name: e2e
on:
push:
tags-ingore:
- '**'
branches:
- master
pull_request:
workflow_dispatch:
jobs:
test:
runs-on: ubuntu-latest

View file

@ -1,8 +1,10 @@
name: unit
on:
push:
tags-ignore:
- '**'
branches:
- master
pull_request:
workflow_dispatch:
jobs:
test:
runs-on: ubuntu-latest

View file

@ -486,6 +486,14 @@ paths:
type: array
items:
$ref: '#/components/schemas/SmartPlaylistRule'
songs:
type: array
description: An array of song IDs to populate the playlist. Only used if the playlist is not a smart one (i.e. `rules` are empty).
items:
type: string
format: md5
required:
- name
'/api/playlist/{playlistId}/songs':
parameters:
- schema:

View file

@ -30,6 +30,8 @@ class SmartPlaylistRuleParameterFactory
Assert::keyExists($ruleParameterMap, $operator);
return is_array($ruleParameterMap[$operator]) ? $ruleParameterMap[$operator] : $ruleParameterMap[$operator]();
return is_callable($ruleParameterMap[$operator])
? $ruleParameterMap[$operator]()
: $ruleParameterMap[$operator];
}
}

View file

@ -42,10 +42,12 @@ class PlaylistController extends Controller
'rules' => $request->rules,
]);
$songs = (array) $request->songs;
if (!$playlist->is_smart) {
$songs = (array) $request->songs;
if ($songs) {
$playlist->songs()->sync($songs);
if ($songs) {
$playlist->songs()->sync($songs);
}
}
$playlistAsArray = $playlist->toArray();

View file

@ -3,10 +3,11 @@
namespace App\Models;
use App\Factories\SmartPlaylistRuleParameterFactory;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Database\Eloquent\Builder;
use Webmozart\Assert\Assert;
class Rule
class Rule implements Arrayable
{
public const OPERATOR_IS = 'is';
public const OPERATOR_IS_NOT = 'isNot';
@ -83,4 +84,21 @@ class Rule
{
return $this->operator === self::OPERATOR_IS_BETWEEN ? 'whereBetween' : 'where';
}
/** @return array<mixed> */
public function toArray(): array
{
return [
'model' => $this->model,
'operator' => $this->operator,
'value' => $this->value,
];
}
public function equals(Rule $rule): bool
{
return $this->operator === $rule->operator
&& $this->value === $rule->value
&& $this->model === $rule->model;
}
}

View file

@ -3,6 +3,7 @@
namespace Tests\Feature;
use App\Models\Playlist;
use App\Models\Rule;
use App\Models\Song;
use App\Models\User;
use Illuminate\Support\Collection;
@ -46,6 +47,56 @@ class PlaylistTest extends TestCase
}
}
public function testCreatingSmartPlaylist(): void
{
/** @var User $user */
$user = User::factory()->create();
$rule = Rule::create([
'model' => 'artist.name',
'operator' => Rule::OPERATOR_IS,
'value' => 'Bob Dylan',
]);
$this->postAsUser('api/playlist', [
'name' => 'Smart Foo Bar',
'rules' => [$rule->toArray()],
], $user);
/** @var Playlist $playlist */
$playlist = Playlist::orderBy('id', 'desc')->first();
self::assertSame('Smart Foo Bar', $playlist->name);
self::assertTrue($playlist->user->is($user));
self::assertTrue($playlist->is_smart);
self::assertCount(1, $playlist->rules);
self::assertTrue(Rule::create($playlist->rules[0])->equals($rule));
}
public function testCreatingSmartPlaylistIgnoresSongs(): void
{
/** @var User $user */
$user = User::factory()->create();
$this->postAsUser('api/playlist', [
'name' => 'Smart Foo Bar',
'rules' => [
Rule::create([
'model' => 'artist.name',
'operator' => Rule::OPERATOR_IS,
'value' => 'Bob Dylan',
])->toArray(),
],
'songs' => Song::orderBy('id')->take(3)->get()->pluck('id')->toArray(),
], $user);
/** @var Playlist $playlist */
$playlist = Playlist::orderBy('id', 'desc')->first();
self::assertSame('Smart Foo Bar', $playlist->name);
self::assertEmpty($playlist->songs);
}
public function testUpdatePlaylistName(): void
{
/** @var User $user */