mirror of
https://github.com/koel/koel
synced 2024-11-10 06:34:14 +00:00
feat(test): add SmartPlaylistService tests (#1616)
This commit is contained in:
parent
dcc0e82a0b
commit
0b486e699b
16 changed files with 542 additions and 263 deletions
|
@ -22,7 +22,7 @@ const models: SmartPlaylistModel[] = [
|
|||
}, {
|
||||
name: 'interactions.play_count',
|
||||
type: 'number',
|
||||
label: 'Plays'
|
||||
label: 'Play Count'
|
||||
}, {
|
||||
name: 'interactions.last_played_at',
|
||||
type: 'date',
|
||||
|
|
|
@ -2,9 +2,549 @@
|
|||
|
||||
namespace Tests\Integration\Services;
|
||||
|
||||
use App\Models\Album;
|
||||
use App\Models\Artist;
|
||||
use App\Models\Interaction;
|
||||
use App\Models\Playlist;
|
||||
use App\Models\Song;
|
||||
use App\Models\User;
|
||||
use App\Services\SmartPlaylistService;
|
||||
use Illuminate\Support\Collection;
|
||||
use Tests\TestCase;
|
||||
|
||||
class SmartPlaylistServiceTest extends TestCase
|
||||
{
|
||||
// @todo write tests
|
||||
private SmartPlaylistService $service;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->service = app(SmartPlaylistService::class);
|
||||
}
|
||||
|
||||
public function testTitleIs(): void
|
||||
{
|
||||
$matches = Song::factory()->count(3)->create(['title' => 'Foo Something']);
|
||||
Song::factory()->count(3)->create(['title' => 'Bar Something']);
|
||||
|
||||
$this->assertMatchesAgainstRules($matches, [
|
||||
[
|
||||
'id' => 1,
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1,
|
||||
'model' => 'title',
|
||||
'operator' => 'is',
|
||||
'value' => ['Foo Something'],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function testTitleIsNot(): void
|
||||
{
|
||||
$matches = Song::factory()->count(3)->create(['title' => 'Foo Something']);
|
||||
Song::factory()->count(3)->create(['title' => 'Bar Something']);
|
||||
|
||||
$this->assertMatchesAgainstRules($matches, [
|
||||
[
|
||||
'id' => 1,
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1,
|
||||
'model' => 'title',
|
||||
'operator' => 'isNot',
|
||||
'value' => ['Bar Something'],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function testTitleContains(): void
|
||||
{
|
||||
$matches = Song::factory()->count(3)->create(['title' => 'Foo Something']);
|
||||
Song::factory()->count(3)->create(['title' => 'Foo Nothing']);
|
||||
|
||||
$this->assertMatchesAgainstRules($matches, [
|
||||
[
|
||||
'id' => 1,
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1,
|
||||
'model' => 'title',
|
||||
'operator' => 'contains',
|
||||
'value' => ['Some'],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function testTitleDoesNotContain(): void
|
||||
{
|
||||
$matches = Song::factory()->count(3)->create(['title' => 'Foo Something']);
|
||||
Song::factory()->count(3)->create(['title' => 'Foo Nothing']);
|
||||
|
||||
$this->assertMatchesAgainstRules($matches, [
|
||||
[
|
||||
'id' => 1,
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1,
|
||||
'model' => 'title',
|
||||
'operator' => 'notContain',
|
||||
'value' => ['Nothing'],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function testTitleBeginsWith(): void
|
||||
{
|
||||
$matches = Song::factory()->count(3)->create(['title' => 'Foo Something']);
|
||||
Song::factory()->count(3)->create(['title' => 'Bar Something']);
|
||||
|
||||
$this->assertMatchesAgainstRules($matches, [
|
||||
[
|
||||
'id' => 1,
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1,
|
||||
'model' => 'title',
|
||||
'operator' => 'beginsWith',
|
||||
'value' => ['Foo'],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function testTitleEndsWith(): void
|
||||
{
|
||||
$matches = Song::factory()->count(3)->create(['title' => 'Foo Something']);
|
||||
Song::factory()->count(3)->create(['title' => 'Foo Nothing']);
|
||||
|
||||
$this->assertMatchesAgainstRules($matches, [
|
||||
[
|
||||
'id' => 1,
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1,
|
||||
'model' => 'title',
|
||||
'operator' => 'endsWith',
|
||||
'value' => ['Something'],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function testAlbumIs(): void
|
||||
{
|
||||
$albums = Album::factory()->count(2)->create(['name' => 'Foo Album']);
|
||||
|
||||
$matches = Song::factory()->count(3)->for($albums[0])->create()
|
||||
->merge(Song::factory()->count(2)->for($albums[1])->create());
|
||||
|
||||
Song::factory()->count(3)->create();
|
||||
|
||||
$this->assertMatchesAgainstRules($matches, [
|
||||
[
|
||||
'id' => 1,
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1,
|
||||
'model' => 'album.name',
|
||||
'operator' => 'is',
|
||||
'value' => ['Foo Album'],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function testArtistIs(): void
|
||||
{
|
||||
$matches = Song::factory()
|
||||
->count(3)
|
||||
->for(Artist::factory()->create(['name' => 'Foo Artist']))
|
||||
->create();
|
||||
|
||||
Song::factory()->count(3)->create();
|
||||
|
||||
$this->assertMatchesAgainstRules($matches, [
|
||||
[
|
||||
'id' => 1,
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1,
|
||||
'model' => 'artist.name',
|
||||
'operator' => 'is',
|
||||
'value' => ['Foo Artist'],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function testGenreIsOrContains(): void
|
||||
{
|
||||
$matches = Song::factory()->count(3)->create(['genre' => 'Foo Genre'])
|
||||
->merge(Song::factory()->count(2)->create(['genre' => 'Bar Genre']));
|
||||
|
||||
Song::factory()->count(3)->create(['genre' => 'Baz Genre']);
|
||||
|
||||
$this->assertMatchesAgainstRules($matches, [
|
||||
[
|
||||
'id' => 1,
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1,
|
||||
'model' => 'genre',
|
||||
'operator' => 'is',
|
||||
'value' => ['Foo Genre'],
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'id' => 2,
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1,
|
||||
'model' => 'genre',
|
||||
'operator' => 'contains',
|
||||
'value' => ['Bar'],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function testYearIsGreaterThan(): void
|
||||
{
|
||||
$matches = Song::factory()->count(3)->create(['year' => 2030])
|
||||
->merge(Song::factory()->count(2)->create(['year' => 2022]));
|
||||
|
||||
Song::factory()->count(3)->create(['year' => 2020]);
|
||||
|
||||
$this->assertMatchesAgainstRules($matches, [
|
||||
[
|
||||
'id' => 1,
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1,
|
||||
'model' => 'year',
|
||||
'operator' => 'isGreaterThan',
|
||||
'value' => [2021],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function testYearIsLessThan(): void
|
||||
{
|
||||
$matches = Song::factory()->count(3)->create(['year' => 1980])
|
||||
->merge(Song::factory()->count(2)->create(['year' => 1978]));
|
||||
|
||||
Song::factory()->count(3)->create(['year' => 1991]);
|
||||
|
||||
$this->assertMatchesAgainstRules($matches, [
|
||||
[
|
||||
'id' => 1,
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1,
|
||||
'model' => 'year',
|
||||
'operator' => 'isLessThan',
|
||||
'value' => [1981],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function testYearIsBetween(): void
|
||||
{
|
||||
$matches = Song::factory()->count(3)->create(['year' => 1980])
|
||||
->merge(Song::factory()->count(2)->create(['year' => 1978]));
|
||||
|
||||
Song::factory()->count(3)->create(['year' => 1991]);
|
||||
|
||||
$this->assertMatchesAgainstRules($matches, [
|
||||
[
|
||||
'id' => 1,
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1,
|
||||
'model' => 'year',
|
||||
'operator' => 'isBetween',
|
||||
'value' => [1970, 1985],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function testPlayCountIsGreaterThan(): void
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = User::factory()->create();
|
||||
$matches = Song::factory()->count(2)->create();
|
||||
|
||||
$notMatch = Song::factory()->create();
|
||||
|
||||
Interaction::factory()
|
||||
->for($matches[0])
|
||||
->for($user)
|
||||
->create(['play_count' => 1000]);
|
||||
|
||||
Interaction::factory()
|
||||
->for($matches[1])
|
||||
->for($user)
|
||||
->create(['play_count' => 2000]);
|
||||
|
||||
Interaction::factory()
|
||||
->for($user)
|
||||
->for($notMatch)
|
||||
->create(['play_count' => 500]);
|
||||
|
||||
$this->assertMatchesAgainstRules($matches, [
|
||||
[
|
||||
'id' => 1,
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1,
|
||||
'model' => 'interactions.play_count',
|
||||
'operator' => 'isGreaterThan',
|
||||
'value' => [999],
|
||||
],
|
||||
],
|
||||
],
|
||||
], $user);
|
||||
}
|
||||
|
||||
public function testLastPlayedAtIsInLast(): void
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = User::factory()->create();
|
||||
$matches = Song::factory()->count(2)->create();
|
||||
|
||||
$notMatch = Song::factory()->create();
|
||||
|
||||
Interaction::factory()
|
||||
->for($matches[0])
|
||||
->for($user)
|
||||
->create(['last_played_at' => now()->subDays(2)]);
|
||||
|
||||
Interaction::factory()
|
||||
->for($matches[1])
|
||||
->for($user)
|
||||
->create(['last_played_at' => now()->subDay()]);
|
||||
|
||||
Interaction::factory()
|
||||
->for($user)
|
||||
->for($notMatch)
|
||||
->count(2)
|
||||
->create(['last_played_at' => now()->subDays(4)]);
|
||||
|
||||
$this->assertMatchesAgainstRules($matches, [
|
||||
[
|
||||
'id' => 1,
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1,
|
||||
'model' => 'interactions.last_played_at',
|
||||
'operator' => 'inLast',
|
||||
'value' => [3],
|
||||
],
|
||||
],
|
||||
],
|
||||
], $user);
|
||||
}
|
||||
|
||||
public function testLastPlayedNotInLast(): void
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = User::factory()->create();
|
||||
$matches = Song::factory()->count(2)->create();
|
||||
|
||||
$notMatch = Song::factory()->create();
|
||||
|
||||
Interaction::factory()
|
||||
->for($matches[0])
|
||||
->for($user)
|
||||
->create(['last_played_at' => now()->subDays(4)]);
|
||||
|
||||
Interaction::factory()
|
||||
->for($matches[1])
|
||||
->for($user)
|
||||
->create(['last_played_at' => now()->subDays(3)]);
|
||||
|
||||
Interaction::factory()
|
||||
->for($user)
|
||||
->for($notMatch)
|
||||
->count(2)
|
||||
->create(['last_played_at' => now()->subDays(2)]);
|
||||
|
||||
$this->assertMatchesAgainstRules($matches, [
|
||||
[
|
||||
'id' => 1,
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1,
|
||||
'model' => 'interactions.last_played_at',
|
||||
'operator' => 'notInLast',
|
||||
'value' => [2],
|
||||
],
|
||||
],
|
||||
],
|
||||
], $user);
|
||||
}
|
||||
|
||||
public function testLastPlayedIs(): void
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = User::factory()->create();
|
||||
$matches = Song::factory()->count(2)->create();
|
||||
|
||||
$notMatch = Song::factory()->create();
|
||||
|
||||
Interaction::factory()
|
||||
->for($matches[0])
|
||||
->for($user)
|
||||
->create(['last_played_at' => now()]);
|
||||
|
||||
Interaction::factory()
|
||||
->for($matches[1])
|
||||
->for($user)
|
||||
->create(['last_played_at' => now()]);
|
||||
|
||||
Interaction::factory()
|
||||
->for($user)
|
||||
->for($notMatch)
|
||||
->count(2)
|
||||
->create(['last_played_at' => now()->subDays(4)]);
|
||||
|
||||
$this->assertMatchesAgainstRules($matches, [
|
||||
[
|
||||
'id' => 1,
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1,
|
||||
'model' => 'interactions.last_played_at',
|
||||
'operator' => 'is',
|
||||
'value' => [now()->format('Y-m-d')],
|
||||
],
|
||||
],
|
||||
],
|
||||
], $user);
|
||||
}
|
||||
|
||||
public function testLengthIsGreaterThan(): void
|
||||
{
|
||||
$matches = Song::factory()->count(3)->create(['length' => 300])
|
||||
->merge(Song::factory()->count(2)->create(['length' => 200]));
|
||||
|
||||
Song::factory()->count(3)->create(['length' => 100]);
|
||||
|
||||
$this->assertMatchesAgainstRules($matches, [
|
||||
[
|
||||
'id' => 1,
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1,
|
||||
'model' => 'length',
|
||||
'operator' => 'isGreaterThan',
|
||||
'value' => [199],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function testLengthIsInBetween(): void
|
||||
{
|
||||
$matches = Song::factory()->count(3)->create(['length' => 300])
|
||||
->merge(Song::factory()->count(2)->create(['length' => 200]));
|
||||
|
||||
Song::factory()->count(3)->create(['length' => 100]);
|
||||
|
||||
$this->assertMatchesAgainstRules($matches, [
|
||||
[
|
||||
'id' => 1,
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1,
|
||||
'model' => 'length',
|
||||
'operator' => 'isBetween',
|
||||
'value' => [199, 301],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function testDateAddedInLast(): void
|
||||
{
|
||||
$matches = Song::factory()->count(3)->create(['created_at' => now()->subDays(2)])
|
||||
->merge(Song::factory()->count(2)->create(['created_at' => now()->subDay()]))
|
||||
->merge(Song::factory()->count(1)->create(['created_at' => today()]));
|
||||
|
||||
Song::factory()->count(3)->create(['created_at' => now()->subDays(4)]);
|
||||
|
||||
$this->assertMatchesAgainstRules($matches, [
|
||||
[
|
||||
'id' => 1,
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1,
|
||||
'model' => 'created_at',
|
||||
'operator' => 'inLast',
|
||||
'value' => [3],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function testDateAddedNotInLast(): void
|
||||
{
|
||||
$matches = Song::factory()->count(3)->create(['created_at' => now()->subDays(4)])
|
||||
->merge(Song::factory()->count(2)->create(['created_at' => now()->subDays(5)]))
|
||||
->merge(Song::factory()->count(1)->create(['created_at' => now()->subDays(6)]));
|
||||
|
||||
Song::factory()->count(3)->create(['created_at' => now()->subDays(2)]);
|
||||
|
||||
$this->assertMatchesAgainstRules($matches, [
|
||||
[
|
||||
'id' => 1,
|
||||
'rules' => [
|
||||
[
|
||||
'id' => 1,
|
||||
'model' => 'created_at',
|
||||
'operator' => 'notInLast',
|
||||
'value' => [3],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
private function assertMatchesAgainstRules(Collection $matches, array $rules, ?User $playlistOwner = null): void
|
||||
{
|
||||
/** @var Playlist $playlist */
|
||||
$playlist = Playlist::factory()
|
||||
->for($playlistOwner ?? User::factory()->create())
|
||||
->create(['rules' => $rules]);
|
||||
|
||||
self::assertEqualsCanonicalizing(
|
||||
$matches->pluck('id')->all(),
|
||||
$this->service->getSongs($playlist)->pluck('id')->all()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
[
|
||||
{
|
||||
"id": 1541356285385,
|
||||
"rules": [
|
||||
{
|
||||
"id": 1541356313181,
|
||||
"model": "title",
|
||||
"operator": "is",
|
||||
"value": [
|
||||
"Foo"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 1542573964152,
|
||||
"model": "album.name",
|
||||
"operator": "isNot",
|
||||
"value": [
|
||||
"Bar"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 1542573971423,
|
||||
"rules": [
|
||||
{
|
||||
"id": 1542573972485,
|
||||
"model": "title",
|
||||
"operator": "is",
|
||||
"value": [
|
||||
"Baz"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 1542573978609,
|
||||
"model": "created_at",
|
||||
"operator": "isGreaterThan",
|
||||
"value": [
|
||||
"2021.10.01"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -1,15 +0,0 @@
|
|||
[
|
||||
{
|
||||
"id": 1541356285385,
|
||||
"rules": [
|
||||
{
|
||||
"id": 1541356313181,
|
||||
"model": "title",
|
||||
"operator": "beginsWith",
|
||||
"value": [
|
||||
"Foo"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -1,15 +0,0 @@
|
|||
[
|
||||
{
|
||||
"id": 1541356285385,
|
||||
"rules": [
|
||||
{
|
||||
"id": 1541356313181,
|
||||
"model": "title",
|
||||
"operator": "contains",
|
||||
"value": [
|
||||
"Foo"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -1,15 +0,0 @@
|
|||
[
|
||||
{
|
||||
"id": 1541356285385,
|
||||
"rules": [
|
||||
{
|
||||
"id": 1541356313181,
|
||||
"model": "title",
|
||||
"operator": "notContain",
|
||||
"value": [
|
||||
"Foo"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -1,15 +0,0 @@
|
|||
[
|
||||
{
|
||||
"id": 1541356285385,
|
||||
"rules": [
|
||||
{
|
||||
"id": 1541356313181,
|
||||
"model": "title",
|
||||
"operator": "endsWith",
|
||||
"value": [
|
||||
"Foo"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -1,15 +0,0 @@
|
|||
[
|
||||
{
|
||||
"id": 1541356285385,
|
||||
"rules": [
|
||||
{
|
||||
"id": 1541356313181,
|
||||
"model": "created_at",
|
||||
"operator": "inLast",
|
||||
"value": [
|
||||
"7"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -1,23 +0,0 @@
|
|||
[
|
||||
{
|
||||
"id": 1541356285385,
|
||||
"rules": [
|
||||
{
|
||||
"id": 1541356313181,
|
||||
"model": "title",
|
||||
"operator": "is",
|
||||
"value": [
|
||||
"Foo"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 1542572962736,
|
||||
"model": "artist.name",
|
||||
"operator": "isNot",
|
||||
"value": [
|
||||
"Bar"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -1,28 +0,0 @@
|
|||
[
|
||||
{
|
||||
"id": 1541356285385,
|
||||
"rules": [
|
||||
{
|
||||
"id": 1541356313181,
|
||||
"model": "title",
|
||||
"operator": "is",
|
||||
"value": [
|
||||
"Foo"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 1542573097361,
|
||||
"rules": [
|
||||
{
|
||||
"id": 1542573098295,
|
||||
"model": "artist.name",
|
||||
"operator": "is",
|
||||
"value": [
|
||||
"Bar"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -1,15 +0,0 @@
|
|||
[
|
||||
{
|
||||
"id": 1541356285385,
|
||||
"rules": [
|
||||
{
|
||||
"id": 1541356313181,
|
||||
"model": "title",
|
||||
"operator": "is",
|
||||
"value": [
|
||||
"Foo"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -1,16 +0,0 @@
|
|||
[
|
||||
{
|
||||
"id": 1541356285385,
|
||||
"rules": [
|
||||
{
|
||||
"id": 1541356313181,
|
||||
"model": "created_at",
|
||||
"operator": "isBetween",
|
||||
"value": [
|
||||
"2021.10.01",
|
||||
"2021.11.01"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -1,15 +0,0 @@
|
|||
[
|
||||
{
|
||||
"id": 1541356285385,
|
||||
"rules": [
|
||||
{
|
||||
"id": 1541356313181,
|
||||
"model": "length",
|
||||
"operator": "isLessThan",
|
||||
"value": [
|
||||
"300"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -1,15 +0,0 @@
|
|||
[
|
||||
{
|
||||
"id": 1541356285385,
|
||||
"rules": [
|
||||
{
|
||||
"id": 1541356313181,
|
||||
"model": "title",
|
||||
"operator": "isNot",
|
||||
"value": [
|
||||
"Foo"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -1,15 +0,0 @@
|
|||
[
|
||||
{
|
||||
"id": 1541356285385,
|
||||
"rules": [
|
||||
{
|
||||
"id": 1541356313181,
|
||||
"model": "created_at",
|
||||
"operator": "notInLast",
|
||||
"value": [
|
||||
"7"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -1,15 +0,0 @@
|
|||
[
|
||||
{
|
||||
"id": 1541356285385,
|
||||
"rules": [
|
||||
{
|
||||
"id": 1541356313181,
|
||||
"model": "interactions.play_count",
|
||||
"operator": "is",
|
||||
"value": [
|
||||
"42"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
Loading…
Reference in a new issue