401 lines
13 KiB
Ruby
401 lines
13 KiB
Ruby
require "rails_helper"
|
|
|
|
RSpec.describe MatchesPresenter do
|
|
let(:project) { build(:project) }
|
|
let(:video_analysis) { instance_double(VideoAnalysis) }
|
|
let(:audio_analysis) { instance_double(AudioAnalysis) }
|
|
|
|
describe "#build_chronological_matches" do
|
|
context "when video analysis success" do
|
|
let(:video) { create(:video, project: project, analysis_status: :success) }
|
|
|
|
it "returns suggested_matches sorted by most recent first" do
|
|
appearance_release = create(:appearance_release, project: project)
|
|
|
|
appearance = BrayniacAI::FacialRecognitionResult.new(external_image_id: "appearance_release_#{appearance_release.id}", start_time: 100)
|
|
allow(video_analysis).to receive(:first_appearances).and_return([appearance])
|
|
|
|
edl_event_response = build(:edl_event,
|
|
channel: "V",
|
|
start_time: 0,
|
|
timecode_in: "00:00:00:00",
|
|
timecode_out: "00:00:01:00",
|
|
matches: [1, 2],
|
|
)
|
|
|
|
results = described_class.new(video, video_analysis, audio_analysis, [edl_event_response], []).build_chronological_matches
|
|
|
|
expect(results.count).to eq 1
|
|
expect(results.first.elapsed_time_until_appearance).to eq 0.12
|
|
expect(results.first.photo.name).to eq "person_photo"
|
|
expect(results.first.name).to eq "Jane Doe"
|
|
expect(results.first.appears_at_timecode).to eq Timecode.new("00:00:00:03")
|
|
end
|
|
end
|
|
|
|
context "when video analysis not success" do
|
|
let(:video) { create(:video, project: project, analysis_status: :pending) }
|
|
|
|
it "returns empty array" do
|
|
expect(described_class.new(video, video_analysis, audio_analysis, [], []).build_chronological_matches).to eq []
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#build_graphics_matches" do
|
|
context "when video analysis success" do
|
|
let(:video) do
|
|
create(:video,
|
|
project: project,
|
|
analysis_status: :success,
|
|
graphics_elements: build_list(:graphics_element, 1, source_file_name: "my_file.mp4", timecode_in: "00:00:00:00")
|
|
)
|
|
end
|
|
|
|
it "returns graphics elements matches sorted by most recent first" do
|
|
earlier_edl_event_response = build(:edl_event,
|
|
start_time: 0,
|
|
timecode_in: "00:00:00:00",
|
|
timecode_out: "00:00:01:00",
|
|
source_file_name: "my_file.mp4",
|
|
)
|
|
later_edl_event_response = build(:edl_event,
|
|
start_time: 100,
|
|
timecode_in: "00:00:10:00",
|
|
timecode_out: "00:00:11:00",
|
|
source_file_name: "another_file.mp4",
|
|
)
|
|
|
|
results = described_class.new(
|
|
video,
|
|
video_analysis,
|
|
audio_analysis,
|
|
[],
|
|
[earlier_edl_event_response, later_edl_event_response],
|
|
).build_graphics_matches
|
|
|
|
expect(results.count).to eq 2
|
|
expect(results.first.start_time).to eq 100
|
|
expect(results.first.elapsed_time_until_appearance).to eq 0.12
|
|
expect(results.first.filename).to eq "another_file.mp4"
|
|
expect(results.first.appears_at_timecode).to eq Timecode.new("00:00:00:03")
|
|
expect(results.first.confirmed).to be false
|
|
expect(results.first.timecode_in).to eq "00:00:10:00"
|
|
expect(results.second.start_time).to eq 0
|
|
expect(results.second.elapsed_time_until_appearance).to eq 0.0
|
|
expect(results.second.appears_at_timecode).to eq Timecode.new("00:00:00:00")
|
|
expect(results.second.filename).to eq "my_file.mp4"
|
|
expect(results.second.confirmed).to be true
|
|
expect(results.second.timecode_in).to eq "00:00:00:00"
|
|
end
|
|
|
|
it "does not return graphics elements matches that have empty source_file_name" do
|
|
null_source_file_edl_event_response = build(:edl_event,
|
|
source_file_name: nil,
|
|
)
|
|
empty_source_file_edl_event_response = build(:edl_event,
|
|
source_file_name: "",
|
|
)
|
|
|
|
results = described_class.new(
|
|
video,
|
|
video_analysis,
|
|
[],
|
|
[
|
|
null_source_file_edl_event_response,
|
|
empty_source_file_edl_event_response,
|
|
],
|
|
[],
|
|
).build_graphics_matches
|
|
|
|
expect(results).to eq []
|
|
end
|
|
end
|
|
|
|
context "when video analysis not success" do
|
|
let(:video) { create(:video, project: project, analysis_status: :pending) }
|
|
|
|
it "returns empty array" do
|
|
expect(described_class.new(video, video_analysis, [], [], []).build_graphics_matches).to eq []
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#build_chronological_audio_matches" do
|
|
context "when audio analysis success" do
|
|
let(:video) { create(:video, project: project, audio_analysis_status: :success) }
|
|
|
|
it "returns audio_matches sorted by most recent first" do
|
|
acquired_media_release = create(:acquired_media_release,
|
|
project: project,
|
|
file_infos: [
|
|
build(:file_info, id: 3, filename: "acquired_media_1")
|
|
]
|
|
)
|
|
music_release = create(:music_release,
|
|
project: project,
|
|
file_infos: [
|
|
build(:file_info, id: 1, filename: "original_music_1"),
|
|
build(:file_info, id: 2, filename: "original_music_2"),
|
|
]
|
|
)
|
|
audio_confirmation = create(:audio_confirmation,
|
|
video: video,
|
|
source_file_name: "original_music_2",
|
|
timecode_in: "00:00:00:00",
|
|
)
|
|
|
|
audio_analysis = OpenStruct.new(
|
|
results: [
|
|
OpenStruct.new(
|
|
uid: "2",
|
|
requested_filename: "original_music_2",
|
|
type: "original_music",
|
|
audio_data: OpenStruct.new(
|
|
filename: "original_music_2",
|
|
composers: [],
|
|
publishers: [],
|
|
catalog: "",
|
|
title: "",
|
|
),
|
|
edl: [
|
|
OpenStruct.new(
|
|
start_time: 0,
|
|
timecode_in: "00:00:00:00",
|
|
),
|
|
]
|
|
),
|
|
OpenStruct.new(
|
|
uid: "1",
|
|
requested_filename: "original_music_1",
|
|
type: "original_music",
|
|
audio_data: OpenStruct.new(
|
|
filename: "original_music_1",
|
|
composers: [],
|
|
publishers: [],
|
|
catalog: "",
|
|
title: "",
|
|
),
|
|
edl: [
|
|
OpenStruct.new(
|
|
start_time: 5000,
|
|
timecode_in: "00:00:05:00",
|
|
),
|
|
]
|
|
),
|
|
OpenStruct.new(
|
|
uid: "3",
|
|
requested_filename: "acquired_media_1",
|
|
type: "acquired_media",
|
|
audio_data: OpenStruct.new(
|
|
filename: "acquired_media_1",
|
|
composers: [],
|
|
publishers: [],
|
|
catalog: "",
|
|
title: "",
|
|
),
|
|
edl: [
|
|
OpenStruct.new(
|
|
start_time: 1000,
|
|
timecode_in: "00:00:01:00",
|
|
),
|
|
]
|
|
),
|
|
OpenStruct.new(
|
|
uid: nil,
|
|
requested_filename: "library_music_1",
|
|
type: "library_music",
|
|
audio_data: OpenStruct.new(
|
|
filename: "library_music_1",
|
|
composers: [OpenStruct.new(name: "Beethoven", affiliation: "Affiliation", percentage: "100.0%")],
|
|
publishers: [OpenStruct.new(name: "Jingle Punks", affiliation: "Affiliation", percentage: "100.0%")],
|
|
catalog: "MIBE",
|
|
title: "Library Music",
|
|
),
|
|
edl: [
|
|
OpenStruct.new(
|
|
start_time: 2000,
|
|
timecode_in: "00:00:02:00",
|
|
),
|
|
]
|
|
),
|
|
]
|
|
)
|
|
|
|
results = described_class.new(
|
|
video,
|
|
video_analysis,
|
|
audio_analysis,
|
|
[],
|
|
[],
|
|
).build_chronological_audio_matches
|
|
|
|
expect(results.count).to eq 4
|
|
expect(results.first).to have_attributes(
|
|
elapsed_time_until_appearance: 5.0,
|
|
filename: "original_music_1",
|
|
appears_at_timecode: Timecode.new("00:00:05:00"),
|
|
timecode_in: "00:00:05:00",
|
|
confirmed: false,
|
|
composer_info: "Beethoven, Affiliation, 100.0%",
|
|
publisher_info: "Jingle Punks, Affiliation, 100.0%",
|
|
catalog: "",
|
|
title: "",
|
|
confirmation_type: "original_music",
|
|
edl_type: "all_tracks",
|
|
)
|
|
expect(results.second).to have_attributes(
|
|
elapsed_time_until_appearance: 2.0,
|
|
filename: "library_music_1",
|
|
appears_at_timecode: Timecode.new("00:00:02:00"),
|
|
timecode_in: "00:00:02:00",
|
|
confirmed: false,
|
|
composer_info: "Beethoven, Affiliation, 100.0%",
|
|
publisher_info: "Jingle Punks, Affiliation, 100.0%",
|
|
catalog: "MIBE",
|
|
title: "Library Music",
|
|
confirmation_type: "library_music",
|
|
edl_type: "all_tracks",
|
|
)
|
|
expect(results.third).to have_attributes(
|
|
elapsed_time_until_appearance: 1.0,
|
|
filename: "acquired_media_1",
|
|
appears_at_timecode: Timecode.new("00:00:01:00"),
|
|
timecode_in: "00:00:01:00",
|
|
confirmed: false,
|
|
composer_info: "",
|
|
publisher_info: "",
|
|
catalog: "",
|
|
title: "",
|
|
confirmation_type: "acquired_media",
|
|
edl_type: "all_tracks",
|
|
)
|
|
expect(results.fourth).to have_attributes(
|
|
elapsed_time_until_appearance: 0.0,
|
|
filename: "original_music_2",
|
|
appears_at_timecode: Timecode.new("00:00:00:00"),
|
|
timecode_in: "00:00:00:00",
|
|
confirmed: true,
|
|
composer_info: "Beethoven, Affiliation, 100.0%",
|
|
publisher_info: "Jingle Punks, Affiliation, 100.0%",
|
|
catalog: "",
|
|
title: "",
|
|
confirmation_type: "original_music",
|
|
edl_type: "all_tracks",
|
|
)
|
|
end
|
|
|
|
context "when audio_only_edl attached" do
|
|
it "returns audio_matches with edl_type " do
|
|
video = create(:video, :with_audio_only_edl_file, project: project, audio_analysis_status: :success)
|
|
audio_analysis = OpenStruct.new(
|
|
results: [
|
|
OpenStruct.new(
|
|
uid: "2",
|
|
requested_filename: "source_file_name",
|
|
type: "acquired_media",
|
|
audio_data: OpenStruct.new(
|
|
filename: "source_file_name",
|
|
composers: [],
|
|
publishers: [],
|
|
catalog: "",
|
|
title: "",
|
|
),
|
|
edl: [
|
|
OpenStruct.new(
|
|
source_file_name: "source_file_name",
|
|
start_time: 0,
|
|
timecode_in: "00:00:00:00",
|
|
),
|
|
]
|
|
),
|
|
]
|
|
)
|
|
|
|
results = described_class.new(
|
|
video,
|
|
video_analysis,
|
|
audio_analysis,
|
|
[],
|
|
[],
|
|
).build_chronological_audio_matches
|
|
|
|
expect(results.first).to have_attributes(
|
|
edl_type: "audio",
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when video analysis not success" do
|
|
let(:video) { create(:video, project: project, audio_analysis_status: :pending) }
|
|
|
|
it "returns empty array" do
|
|
expect(described_class.new(video, video_analysis, audio_analysis, [], []).build_chronological_audio_matches).to eq []
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#all_tracks_edl_events" do
|
|
let(:video) { create(:video, project: project, analysis_status: :pending) }
|
|
|
|
it "returns edl events sorted by start time ascending" do
|
|
earlier_edl_event_response = build(:edl_event,
|
|
channel: "V",
|
|
start_time: 0,
|
|
timecode_in: "00:00:00:00",
|
|
timecode_out: "00:00:01:00",
|
|
duration: 1,
|
|
source_file_name: "my_file.mp4",
|
|
clip_name: "my_clip.mp4",
|
|
description: "This is a great clip",
|
|
matches: [],
|
|
)
|
|
later_edl_event_response = build(:edl_event,
|
|
channel: "A1",
|
|
start_time: 100,
|
|
timecode_in: "00:00:10:00",
|
|
timecode_out: "00:00:11:00",
|
|
duration: 1,
|
|
source_file_name: "another_file.mp4",
|
|
clip_name: "another_clip.mp4",
|
|
description: "This is a great clip",
|
|
matches: [],
|
|
)
|
|
|
|
results = described_class.new(
|
|
video,
|
|
video_analysis,
|
|
audio_analysis,
|
|
[earlier_edl_event_response, later_edl_event_response],
|
|
[],
|
|
).all_tracks_edl_events
|
|
|
|
expect(results).to eq [
|
|
EdlEvent.new(
|
|
channel: "V",
|
|
start_time: 0,
|
|
timecode_in: "00:00:00:00",
|
|
timecode_out: "00:00:01:00",
|
|
duration: 1,
|
|
source_file_name: "my_file.mp4",
|
|
clip_name: "my_clip.mp4",
|
|
description: "This is a great clip",
|
|
matches: [],
|
|
),
|
|
EdlEvent.new(
|
|
channel: "A1",
|
|
start_time: 100,
|
|
timecode_in: "00:00:10:00",
|
|
timecode_out: "00:00:11:00",
|
|
duration: 1,
|
|
source_file_name: "another_file.mp4",
|
|
clip_name: "another_clip.mp4",
|
|
description: "This is a great clip",
|
|
matches: [],
|
|
),
|
|
]
|
|
end
|
|
end
|
|
end
|