diff --git a/app/Models/Interaction.php b/app/Models/Interaction.php index 60e14016..671c8ada 100644 --- a/app/Models/Interaction.php +++ b/app/Models/Interaction.php @@ -11,6 +11,7 @@ use Illuminate\Database\Eloquent\Model; * @property int play_count * @property Song song * @property User user + * @property int id */ class Interaction extends Model { diff --git a/app/Models/Song.php b/app/Models/Song.php index c37a6c38..605e4e75 100644 --- a/app/Models/Song.php +++ b/app/Models/Song.php @@ -352,4 +352,9 @@ class Song extends Model return compact('bucket', 'key'); } + + public function __toString() + { + return $this->id; + } } diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php index 6c5279ca..90fc6b96 100644 --- a/database/factories/ModelFactory.php +++ b/database/factories/ModelFactory.php @@ -52,3 +52,12 @@ $factory->define(App\Models\Playlist::class, function ($faker) { 'name' => $faker->name, ]; }); + +$factory->define(\App\Models\Interaction::class, function ($faker) { + return [ + 'song_id' => factory(\App\Models\Song::class)->create()->id, + 'user_id' => factory(\App\Models\User::class)->create()->id, + 'liked' => $faker->boolean, + 'play_count' => $faker->randomNumber, + ]; +}); diff --git a/tests/Unit/InteractionTest.php b/tests/Unit/InteractionTest.php new file mode 100644 index 00000000..81d24d1b --- /dev/null +++ b/tests/Unit/InteractionTest.php @@ -0,0 +1,93 @@ +assertInstanceOf(Interaction::class, new Interaction()); + } + + /** @test */ + public function it_increases_a_songs_play_count() + { + // Given an interaction + /** @var Interaction $interaction */ + $interaction = factory(Interaction::class)->create(); + + // When I call the method to increases the song's play count + Interaction::increasePlayCount($interaction->song, $interaction->user); + + // Then I see the play count is increased + /** @var Interaction $interaction */ + $updatedInteraction = Interaction::find($interaction->id); + $this->assertEquals($interaction->play_count + 1, $updatedInteraction->play_count); + } + + /** @test */ + public function it_toggles_like_status() + { + $this->expectsEvents(SongLikeToggled::class); + + // Given an interaction + $interaction = factory(Interaction::class)->create(); + + // When I call the method to toggle the song's like status by user + Interaction::toggleLike($interaction->song, $interaction->user); + + // Then I see the interaction's like status is toggled + /** @var Interaction $interaction */ + $updatedInteraction = Interaction::find($interaction->id); + $this->assertNotSame($interaction->liked, $updatedInteraction->liked); + } + + /** @test */ + public function user_can_like_multiple_songs_at_once() + { + $this->expectsEvents(SongLikeToggled::class); + + // Given multiple song and a user + /** @var Collection $songs */ + $songs = factory(Song::class, 2)->create(); + $user = factory(User::class)->create(); + + // When I call the method to like songs in batch + Interaction::batchLike($songs->pluck('id')->all(), $user); + + // Then I see the songs are all liked + $songs->each(function (Song $song) use ($user) { + $this->assertTrue(Interaction::whereSongIdAndUserId($song->id, $user->id)->first()->liked); + }); + } + + /** @test */ + public function user_can_unlike_multiple_songs_at_once() + { + $this->expectsEvents(SongLikeToggled::class); + + // Given multiple interaction records + $user = factory(User::class)->create(); + /** @var Collection $interactions */ + $interactions = factory(Interaction::class, 3)->create([ + 'user_id' => $user->id, + 'liked' => true, + ]); + + // When I call the method to like songs in batch + Interaction::batchUnlike($interactions->pluck('song.id')->all(), $user); + + // Then I see the songs are all liked + $interactions->each(function (Interaction $interaction) { + $this->assertFalse(Interaction::find($interaction->id)->liked); + }); + } +}