Skip to content

Commit

Permalink
Complete the test
Browse files Browse the repository at this point in the history
  • Loading branch information
aidewoode committed Jul 5, 2024
1 parent 66428bb commit d4f0e42
Show file tree
Hide file tree
Showing 11 changed files with 262 additions and 155 deletions.
19 changes: 10 additions & 9 deletions app/jobs/media_sync_all_job.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
# frozen_string_literal: true

class MediaSyncAllJob < MediaSyncJob
after_perform do
Media.syncing = false
Media.instance.broadcast_render_to "media_sync", partial: "media_syncing/syncing", locals: {syncing: false}
Media.fetch_external_metadata
end

def perform
file_paths = MediaFile.file_paths(Setting.media_path)
def perform(dir = Setting.media_path)
file_paths = MediaFile.file_paths(dir)
parallel_processor_count = self.class.config.parallel_processor_count
file_md5_hashes = Parallel.map(file_paths, in_processes: parallel_processor_count) do |file_path|
MediaFile.get_md5_hash(file_path, with_mtime: true)
Expand All @@ -19,12 +13,19 @@ def perform

return if added_file_paths.blank?

grouped_file_paths = added_file_paths.in_groups(parallel_processor_count, false).compact_blank
grouped_file_paths = (parallel_processor_count > 0) ? added_file_paths.in_groups(parallel_processor_count, false).compact_blank : [added_file_paths]

added_song_hashes = Parallel.map(grouped_file_paths, in_processes: parallel_processor_count) do |paths|
Media.sync(:added, paths)
end.flatten.compact

Media.clean_up(added_song_hashes + existing_songs.pluck(:md5_hash))
end

private

def after_sync(_)
Media.instance.broadcast_render_to "media_sync", partial: "media_syncing/syncing", locals: {syncing: false}
super(fetch_external_metadata: true)
end
end
21 changes: 14 additions & 7 deletions app/jobs/media_sync_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,30 @@ class MediaSyncJob < ApplicationJob
# Limits the concurrency to 1 to prevent inconsistent media syncing data.
limits_concurrency to: 1, key: :media_sync

before_perform do
Media.syncing = true
end
before_perform :before_sync

after_perform do |job|
sync_type = job.arguments.first

Media.syncing = false
Media.fetch_external_metadata unless sync_type == :removed
after_sync(fetch_external_metadata: sync_type != :removed)
end

def perform(type, file_paths = [])
parallel_processor_count = self.class.config.parallel_processor_count
grouped_file_paths = file_paths.in_groups(parallel_processor_count, false).compact_blank
grouped_file_paths = (parallel_processor_count > 0) ? file_paths.in_groups(parallel_processor_count, false).compact_blank : [file_paths]

Parallel.each grouped_file_paths, in_processes: parallel_processor_count do |paths|
Media.sync(type, paths)
end
end

private

def before_sync
Media.syncing = true
end

def after_sync(fetch_external_metadata: true)
Media.syncing = false
Media.fetch_external_metadata if fetch_external_metadata
end
end
2 changes: 2 additions & 0 deletions app/models/media.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ def add_files(file_paths)
file_paths.map do |file_path|
file_info = MediaFile.file_info(file_path)
file_info[:md5_hash] if attach(file_info)
rescue
next
end.compact
end

Expand Down
2 changes: 1 addition & 1 deletion test/controllers/media_syncing_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class MediaSyncingControllerTest < ActionDispatch::IntegrationTest
login users(:admin)

Media.stub(:syncing?, false) do
assert_enqueued_with(job: MediaSyncJob) do
assert_enqueued_with(job: MediaSyncAllJob) do
post media_syncing_url
end
end
Expand Down
154 changes: 154 additions & 0 deletions test/jobs/media_sync_all_job_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# frozen_string_literal: true

require "test_helper"

class MediaSyncAllJobTest < ActiveJob::TestCase
setup do
clear_media_data
MediaSyncAllJob.perform_now
end

test "should create all records in database when synced" do
assert_equal 3, Artist.count
assert_equal 4, Album.count
assert_equal 9, Song.count
end

test "should create associations between artists and albums" do
assert_equal Album.where(name: %w[album1 album2]).ids.sort, Artist.find_by(name: "artist1").albums.ids.sort
assert_equal Album.where(name: "album3").ids.sort, Artist.find_by(name: "artist2").albums.ids.sort
assert_equal Album.where(name: "album4").ids.sort, Artist.find_by(various: true).albums.ids.sort
end

test "should create associations between albums and songs" do
album1_songs_ids = Song.where(name: %w[flac_sample m4a_sample]).ids.sort
album2_songs_ids = Song.where(name: "mp3_sample").ids.sort
album3_songs_ids = Song.where(name: %w[ogg_sample wav_sample opus_sample oga_sample wma_sample]).ids.sort
album4_songs_ids = Song.where(name: %w[various_artists_sample]).ids.sort

assert_equal album1_songs_ids, Album.find_by(name: "album1").songs.ids.sort
assert_equal album2_songs_ids, Album.find_by(name: "album2").songs.ids.sort
assert_equal album3_songs_ids, Album.find_by(name: "album3").songs.ids.sort
assert_equal album4_songs_ids, Album.find_by(name: "album4").songs.ids.sort
end

test "should create associations between artists and songs" do
artist1_songs_ids = Song.where(name: %w[flac_sample mp3_sample m4a_sample various_artists_sample]).ids.sort
artist2_songs_ids = Song.where(name: %w[ogg_sample wav_sample opus_sample oga_sample wma_sample]).ids.sort

assert_equal artist1_songs_ids, Artist.find_by(name: "artist1").songs.ids.sort
assert_equal artist2_songs_ids, Artist.find_by(name: "artist2").songs.ids.sort
assert_equal [], Artist.find_by(various: true).songs.ids.sort
end

test "should change associations when modify album info on file" do
stub_file_metadata(file_fixture("artist1_album2.mp3"), album_name: "album1") do
MediaSyncAllJob.perform_now

album1_songs_ids = Song.where(name: %w[flac_sample m4a_sample mp3_sample]).ids.sort

assert_equal Album.where(name: "album1").ids.sort, Artist.find_by(name: "artist1").albums.ids.sort
assert_equal album1_songs_ids, Album.find_by(name: "album1").songs.ids.sort
end
end

test "should change associations when modify artist info on file" do
stub_file_metadata(file_fixture("artist1_album2.mp3"), artist_name: "artist2", albumartist_name: "artist2") do
MediaSyncAllJob.perform_now

artist2_songs_ids = Song.where(
name: %w[mp3_sample ogg_sample wav_sample opus_sample oga_sample wma_sample]
).ids.sort

assert_equal Album.where(name: %w[album2 album3]).ids.sort, Artist.find_by(name: "artist2").albums.ids.sort
assert_equal artist2_songs_ids, Artist.find_by(name: "artist2").songs.ids.sort
end
end

test "should change song attribute when modify song info on file" do
stub_file_metadata(file_fixture("artist1_album2.mp3"), tracknum: 2) do
assert_changes -> { Song.find_by(name: "mp3_sample").tracknum }, from: 1, to: 2 do
MediaSyncAllJob.perform_now
end
end
end

test "should clear records on database when delete file" do
create_tmp_dir(from: Setting.media_path) do |tmp_dir|
File.delete File.join(tmp_dir, "artist2_album3.ogg")
File.delete File.join(tmp_dir, "artist2_album3.wav")
File.delete File.join(tmp_dir, "artist2_album3.opus")
File.delete File.join(tmp_dir, "artist2_album3.oga")
File.delete File.join(tmp_dir, "artist2_album3.wma")

MediaSyncAllJob.perform_now(tmp_dir)

assert_nil Song.find_by(name: "ogg_sample")
assert_nil Song.find_by(name: "wav_sample")
assert_nil Song.find_by(name: "opus_sample")
assert_nil Song.find_by(name: "oga_sample")
assert_nil Song.find_by(name: "wma_sample")
assert_nil Album.find_by(name: "album3")
assert_nil Artist.find_by(name: "artist2")
end
end

test "should broadcast media sync stream when sync all completed" do
assert_broadcasts("media_sync", 1) do
MediaSyncAllJob.perform_now
end
end

test "should not attach record when file path is invalide" do
clear_media_data

create_tmp_dir do |tmp_dir|
FileUtils.touch File.join(tmp_dir, "fake.mp3")
FileUtils.cp file_fixture("artist1_album2.mp3"), File.join(tmp_dir, "artist1_album2.mp3")

MediaSyncAllJob.perform_now(tmp_dir)
assert_equal 1, Album.count
end
end

test "should not attach record when file info is invalide" do
clear_media_data

file_info = {
name: "",
album_name: "",
artist_name: "",
albumartist_name: ""
}

MediaFile.stub(:file_info, file_info) do
MediaSyncAllJob.perform_now
assert_equal 0, Album.count
end
end

test "should change syncing status" do
assert_not Media.syncing?

mock = Minitest::Mock.new
mock.expect(:call, true, [true])
mock.expect(:call, true, [false])

MediaSyncAllJob.perform_later

Media.stub(:syncing=, mock) do
perform_enqueued_jobs
mock.verify
end
end

test "should fetch external metadata from discogs after synced" do
Setting.update(discogs_token: "fake_token")

jobs_count = Album.lack_metadata.count + Artist.lack_metadata.count

assert_enqueued_jobs jobs_count, only: AttachCoverImageFromDiscogsJob do
MediaSyncAllJob.perform_now
end
end
end
39 changes: 29 additions & 10 deletions test/jobs/media_sync_job_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,8 @@
require "test_helper"

class MediaSyncJobTest < ActiveJob::TestCase
test "sync all media" do
mock = Minitest::Mock.new
mock.expect(:call, true, [])

MediaSyncJob.perform_later

Media.stub(:sync_all, mock) do
perform_enqueued_jobs
mock.verify
end
setup do
clear_media_data
end

test "sync added media" do
Expand Down Expand Up @@ -56,4 +48,31 @@ class MediaSyncJobTest < ActiveJob::TestCase
mock.verify
end
end

test "should change syncing status" do
assert_not Media.syncing?

mock = Minitest::Mock.new
mock.expect(:call, true, [true])
mock.expect(:call, true, [false])

MediaSyncJob.perform_later(:added, [fixtures_file_path("artist1_album1.flac")])

Media.stub(:syncing=, mock) do
perform_enqueued_jobs
mock.verify
end
end

test "should fetch external metadata unless sync type is removed" do
Setting.update(discogs_token: "fake_token")

assert_enqueued_jobs 2, only: AttachCoverImageFromDiscogsJob do
MediaSyncJob.perform_now(:added, [fixtures_file_path("artist1_album1.flac"), fixtures_file_path("artist2_album3.wav")])
end

assert_no_enqueued_jobs only: AttachCoverImageFromDiscogsJob do
MediaSyncJob.perform_now(:removed, [fixtures_file_path("artist1_album1.flac")])
end
end
end
5 changes: 4 additions & 1 deletion test/models/album_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
class AlbumTest < ActiveSupport::TestCase
test "should not have same name album on an artist" do
artists(:artist1).albums.create(name: "best")
assert_not artists(:artist1).albums.build(name: "best").valid?

assert_raise ActiveRecord::RecordNotUnique do
artists(:artist1).albums.create(name: "best")
end
end

test "should have default name when name is empty" do
Expand Down
6 changes: 6 additions & 0 deletions test/models/artist_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,10 @@ class ArtistTest < ActiveSupport::TestCase
test "should use default sort when use invalid sort value" do
assert_equal %w[artist1 artist2 various_artists], Artist.sort_records(:invalid).pluck(:name).compact
end

test "should not have same name artist" do
assert_raise ActiveRecord::RecordNotUnique do
Artist.create(name: "artist1")
end
end
end
Loading

0 comments on commit d4f0e42

Please sign in to comment.