require 'rails_helper' describe PendingAnalysis do describe '.poll' do it 'polls videos with pending video analysis' do allow(PendingAnalysis::PendingVideoAnalysis).to receive(:poll) PendingAnalysis.poll expect(PendingAnalysis::PendingVideoAnalysis).to have_received(:poll) end it 'polls videos with pending audio analysis' do allow(PendingAnalysis::PendingAudioAnalysis).to receive(:poll) PendingAnalysis.poll expect(PendingAnalysis::PendingAudioAnalysis).to have_received(:poll) end end describe '.expire' do let(:age_threshold) { 2.days.ago } it 'expires videos with pending video analysis' do allow(PendingAnalysis::PendingVideoAnalysis).to receive(:expire) PendingAnalysis.expire(age_threshold) expect(PendingAnalysis::PendingVideoAnalysis).to have_received(:expire).with(age_threshold) end it 'expires videos with pending audio analysis' do allow(PendingAnalysis::PendingAudioAnalysis).to receive(:expire) PendingAnalysis.expire(age_threshold) expect(PendingAnalysis::PendingAudioAnalysis).to have_received(:expire).with(age_threshold) end end describe PendingAnalysis::PendingVideoAnalysis do describe '.poll' do it 'polls all videos with pending analysis' do pending_analysis = create(:video, analysis_status: :pending, analysis_uid: "pending_uid") not_pending_analysis = create(:video, analysis_status: :success, analysis_uid: "not_pending_uid") allow(described_class).to receive(:new).and_return(spy) described_class.poll expect(described_class).to have_received(:new).with("pending_uid") expect(described_class).not_to have_received(:new).with("not_pending_uid") end end describe '.expire' do it 'expires all videos with pending analysis older than a given time' do pending_analysis_inside_range = create(:video, analysis_status: :pending, analysis_uid: "pending_inside_uid", analysis_started_at: 1.week.ago) pending_analysis_outside_range = create(:video, analysis_status: :pending, analysis_uid: "pending_outside_uid", analysis_started_at: 1.minute.ago) not_pending_analysis = create(:video, analysis_status: :success, analysis_uid: "not_pending_uid") allow(described_class).to receive(:new).and_return(spy) described_class.expire(1.day.ago) expect(described_class).to have_received(:new).with("pending_inside_uid") expect(described_class).not_to have_received(:new).with("pending_outside_uid") expect(described_class).not_to have_received(:new).with("not_pending_uid") end end describe '#poll' do let(:video) { create(:video, analysis_status: :pending, analysis_uid: "analysis_uid") } subject { PendingAnalysis::PendingVideoAnalysis.new(video.analysis_uid) } context 'when API results are present' do it 'updates the video analysis status to success' do allow(BrayniacAI::FacialRecognition).to( receive(:find).and_return(BrayniacAI::FacialRecognition.new({ results: {} })) ) subject.poll expect(video.reload).to be_analysis_success end end context 'when API results are not present' do it 'does nothing' do allow(BrayniacAI::FacialRecognition).to receive(:find).and_return(BrayniacAI::FacialRecognition.new) subject.poll expect(video.reload).to be_analysis_pending end end context 'when API resource is not found' do it 'does nothing' do error = ActiveResource::ResourceNotFound.new('') allow(BrayniacAI::FacialRecognition).to receive(:find).and_raise(error) subject.poll expect(video.reload).to be_analysis_pending end end context 'when API server error occurs' do before do allow(Rails.logger).to receive(:error) allow(subject).to receive(:puts) end it 'does nothing' do error = ActiveResource::ServerError.new('') allow(BrayniacAI::FacialRecognition).to receive(:find).and_raise(error) subject.poll expect(video.reload).to be_analysis_pending end it 'prints error message to logger' do error = ActiveResource::ServerError.new('') allow(BrayniacAI::FacialRecognition).to receive(:find).and_raise(error) subject.poll expect(Rails.logger).to have_received(:error) expect(subject).to have_received(:puts) end end end describe '#expire' do let(:video) { create(:video, analysis_status: :pending, analysis_uid: "analysis_uid") } subject { PendingAnalysis::PendingVideoAnalysis.new(video.analysis_uid) } context 'when API results are present' do it 'updates the video analysis status to success' do allow(BrayniacAI::FacialRecognition).to( receive(:find).and_return(BrayniacAI::FacialRecognition.new({ results: {} })) ) subject.expire expect(video.reload).to be_analysis_success end end context 'when API results are not present' do it 'updates the video analysis status to failure' do allow(BrayniacAI::FacialRecognition).to receive(:find).and_return(BrayniacAI::FacialRecognition.new) subject.expire expect(video.reload).to be_analysis_failure end end context 'when API resource is not found' do it 'updates the video analysis status to failure' do error = ActiveResource::ResourceNotFound.new('') allow(BrayniacAI::FacialRecognition).to receive(:find).and_raise(error) subject.expire expect(video.reload).to be_analysis_failure end end context 'when API server error occurs' do before do allow(Rails.logger).to receive(:error) allow(subject).to receive(:puts) end it 'does nothing' do error = ActiveResource::ServerError.new('') allow(BrayniacAI::FacialRecognition).to receive(:find).and_raise(error) subject.poll expect(video.reload).to be_analysis_pending end it 'prints error message to logger' do error = ActiveResource::ServerError.new('') allow(BrayniacAI::FacialRecognition).to receive(:find).and_raise(error) subject.poll expect(Rails.logger).to have_received(:error) expect(subject).to have_received(:puts) end end end end describe PendingAnalysis::PendingAudioAnalysis do describe '.poll' do it 'polls all videos with pending audio analysis' do pending_analysis = create(:video, audio_analysis_status: :pending, audio_analysis_uid: "pending_uid") not_pending_analysis = create(:video, audio_analysis_status: :success, audio_analysis_uid: "not_pending_uid") allow(described_class).to receive(:new).and_return(spy) described_class.poll expect(described_class).to have_received(:new).with("pending_uid") expect(described_class).not_to have_received(:new).with("not_pending_uid") end end describe '.expire' do it 'expires all videos with pending analysis older than a given time' do pending_analysis_inside_range = create(:video, audio_analysis_status: :pending, audio_analysis_uid: "pending_inside_uid", audio_analysis_started_at: 1.week.ago) pending_analysis_outside_range = create(:video, audio_analysis_status: :pending, audio_analysis_uid: "pending_outside_uid", audio_analysis_started_at: 1.minute.ago) not_pending_analysis = create(:video, analysis_status: :success, analysis_uid: "not_pending_uid") allow(described_class).to receive(:new).and_return(spy) described_class.expire(1.day.ago) expect(described_class).to have_received(:new).with("pending_inside_uid") expect(described_class).not_to have_received(:new).with("pending_outside_uid") expect(described_class).not_to have_received(:new).with("not_pending_uid") end end describe '#poll' do let(:video) { create(:video, audio_analysis_status: :pending, audio_analysis_uid: "analysis_uid") } subject { PendingAnalysis::PendingAudioAnalysis.new(video.audio_analysis_uid) } context 'when API results are present' do it 'updates the audio analysis status to success' do allow(BrayniacAI::AudioRecognition).to( receive(:find).and_return(OpenStruct.new({ results: {} })) ) subject.poll expect(video.reload).to be_audio_analysis_success end end context 'when API results are not present' do it 'does nothing' do allow(BrayniacAI::AudioRecognition).to receive(:find).and_return(BrayniacAI::AudioRecognition.new) subject.poll expect(video.reload).to be_audio_analysis_pending end end context 'when API resource is not found' do it 'does nothing' do error = ActiveResource::ResourceNotFound.new('') allow(BrayniacAI::AudioRecognition).to receive(:find).and_raise(error) subject.poll expect(video.reload).to be_audio_analysis_pending end end context 'when API server error occurs' do before do allow(Rails.logger).to receive(:error) allow(subject).to receive(:puts) end it 'does nothing' do error = ActiveResource::ServerError.new('') allow(BrayniacAI::AudioRecognition).to receive(:find).and_raise(error) subject.poll expect(video.reload).to be_audio_analysis_pending end it 'prints error message to logger' do error = ActiveResource::ServerError.new('') allow(BrayniacAI::AudioRecognition).to receive(:find).and_raise(error) subject.poll expect(Rails.logger).to have_received(:error) expect(subject).to have_received(:puts) end end end describe '#expire' do let(:video) { create(:video, audio_analysis_status: :pending, audio_analysis_uid: "analysis_uid") } subject { PendingAnalysis::PendingAudioAnalysis.new(video.audio_analysis_uid) } context 'when API results are present' do it 'updates the audio analysis status to success' do allow(BrayniacAI::AudioRecognition).to( receive(:find).and_return(BrayniacAI::AudioRecognition.new({ results: {} })) ) subject.expire expect(video.reload).to be_audio_analysis_success end end context 'when API results are not present' do it 'updates the audio analysis status to failure' do allow(BrayniacAI::AudioRecognition).to receive(:find).and_return(BrayniacAI::AudioRecognition.new) subject.expire expect(video.reload).to be_audio_analysis_failure end end context 'when API resource is not found' do it 'updates the audio analysis status to failure' do error = ActiveResource::ResourceNotFound.new('') allow(BrayniacAI::AudioRecognition).to receive(:find).and_raise(error) subject.expire expect(video.reload).to be_audio_analysis_failure end end context 'when API server error occurs' do before do allow(Rails.logger).to receive(:error) allow(subject).to receive(:puts) end it 'does nothing' do error = ActiveResource::ServerError.new('') allow(BrayniacAI::AudioRecognition).to receive(:find).and_raise(error) subject.poll expect(video.reload).to be_audio_analysis_pending end it 'prints error message to logger' do error = ActiveResource::ServerError.new('') allow(BrayniacAI::AudioRecognition).to receive(:find).and_raise(error) subject.poll expect(Rails.logger).to have_received(:error) expect(subject).to have_received(:puts) end end end end end