active_encode 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +26 -18
  3. data/.rubocop_todo.yml +3 -0
  4. data/active_encode.gemspec +3 -0
  5. data/lib/active_encode/base.rb +1 -2
  6. data/lib/active_encode/engine_adapters.rb +1 -0
  7. data/lib/active_encode/engine_adapters/elastic_transcoder_adapter.rb +5 -4
  8. data/lib/active_encode/engine_adapters/ffmpeg_adapter.rb +86 -30
  9. data/lib/active_encode/engine_adapters/pass_through_adapter.rb +239 -0
  10. data/lib/active_encode/errors.rb +6 -0
  11. data/lib/active_encode/persistence.rb +5 -3
  12. data/lib/active_encode/version.rb +1 -1
  13. data/spec/controllers/encode_record_controller_spec.rb +2 -2
  14. data/spec/fixtures/ffmpeg/cancelled-id/cancelled +0 -0
  15. data/spec/fixtures/file with space.low.mp4 +0 -0
  16. data/spec/fixtures/file with space.mp4 +0 -0
  17. data/spec/fixtures/fireworks.low.mp4 +0 -0
  18. data/spec/fixtures/pass_through/cancelled-id/cancelled +0 -0
  19. data/spec/fixtures/pass_through/cancelled-id/input_metadata +90 -0
  20. data/spec/fixtures/pass_through/completed-id/completed +0 -0
  21. data/spec/fixtures/pass_through/completed-id/input_metadata +102 -0
  22. data/spec/fixtures/pass_through/completed-id/output_metadata-high +90 -0
  23. data/spec/fixtures/pass_through/completed-id/output_metadata-low +90 -0
  24. data/spec/fixtures/pass_through/completed-id/video-high.mp4 +0 -0
  25. data/spec/fixtures/pass_through/completed-id/video-low.mp4 +0 -0
  26. data/spec/fixtures/pass_through/failed-id/error.log +1 -0
  27. data/spec/fixtures/pass_through/failed-id/input_metadata +90 -0
  28. data/spec/fixtures/pass_through/running-id/input_metadata +90 -0
  29. data/spec/integration/ffmpeg_adapter_spec.rb +66 -2
  30. data/spec/integration/pass_through_adapter_spec.rb +151 -0
  31. data/spec/shared_specs/engine_adapter_specs.rb +7 -8
  32. metadata +50 -2
@@ -0,0 +1,90 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <MediaInfo
3
+ xmlns="https://mediaarea.net/mediainfo"
4
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5
+ xsi:schemaLocation="https://mediaarea.net/mediainfo https://mediaarea.net/mediainfo/mediainfo_2_0.xsd"
6
+ version="2.0">
7
+ <creatingLibrary version="18.05" url="https://mediaarea.net/MediaInfo">MediaInfoLib</creatingLibrary>
8
+ <media ref="file:///Bars_512kb.mp4">
9
+ <track type="General">
10
+ <VideoCount>1</VideoCount>
11
+ <AudioCount>1</AudioCount>
12
+ <FileExtension>mp4</FileExtension>
13
+ <Format>MPEG-4</Format>
14
+ <Format_Profile>Base Media</Format_Profile>
15
+ <CodecID>isom</CodecID>
16
+ <FileSize>24876</FileSize>
17
+ <Duration>4.928</Duration>
18
+ <OverallBitRate_Mode>VBR</OverallBitRate_Mode>
19
+ <OverallBitRate>40383</OverallBitRate>
20
+ <FrameRate>1.000</FrameRate>
21
+ <FrameCount>1</FrameCount>
22
+ <StreamSize>3216</StreamSize>
23
+ <HeaderSize>3208</HeaderSize>
24
+ <DataSize>21668</DataSize>
25
+ <FooterSize>0</FooterSize>
26
+ <IsStreamable>Yes</IsStreamable>
27
+ <Title>Bars - http://www.archive.org/details/ColorBarsWTone</Title>
28
+ <Movie>Bars - http://www.archive.org/details/ColorBarsWTone</Movie>
29
+ <Recorded_Date>2008</Recorded_Date>
30
+ <Encoded_Date>UTC 1970-01-01 00:00:00</Encoded_Date>
31
+ <Tagged_Date>UTC 2008-11-23 18:44:25</Tagged_Date>
32
+ <Encoded_Application>Lavf51.10.0</Encoded_Application>
33
+ <Comment>license: http://creativecommons.org/licenses/publicdomain/</Comment>
34
+ </track>
35
+ <track type="Video">
36
+ <StreamOrder>0</StreamOrder>
37
+ <ID>1</ID>
38
+ <Format>AVC</Format>
39
+ <Format_Profile>Baseline</Format_Profile>
40
+ <Format_Level>1.3</Format_Level>
41
+ <Format_Settings_CABAC>No</Format_Settings_CABAC>
42
+ <Format_Settings_RefFrames>1</Format_Settings_RefFrames>
43
+ <CodecID>avc1</CodecID>
44
+ <Duration>1.000</Duration>
45
+ <BitRate>18504</BitRate>
46
+ <Width>360</Width>
47
+ <Height>240</Height>
48
+ <Stored_Width>368</Stored_Width>
49
+ <Sampled_Width>360</Sampled_Width>
50
+ <Sampled_Height>240</Sampled_Height>
51
+ <PixelAspectRatio>1.000</PixelAspectRatio>
52
+ <DisplayAspectRatio>1.500</DisplayAspectRatio>
53
+ <Rotation>0.000</Rotation>
54
+ <FrameRate_Mode>CFR</FrameRate_Mode>
55
+ <FrameRate>1.000</FrameRate>
56
+ <FrameRate_Original>0.200</FrameRate_Original>
57
+ <FrameCount>1</FrameCount>
58
+ <ColorSpace>YUV</ColorSpace>
59
+ <ChromaSubsampling>4:2:0</ChromaSubsampling>
60
+ <BitDepth>8</BitDepth>
61
+ <ScanType>Progressive</ScanType>
62
+ <StreamSize>2313</StreamSize>
63
+ <Encoded_Date>UTC 1970-01-01 00:00:00</Encoded_Date>
64
+ <Tagged_Date>UTC 1970-01-01 00:00:00</Tagged_Date>
65
+ </track>
66
+ <track type="Audio">
67
+ <StreamOrder>1</StreamOrder>
68
+ <ID>2</ID>
69
+ <Format>AAC</Format>
70
+ <Format_Profile>LC</Format_Profile>
71
+ <CodecID>mp4a-40-2</CodecID>
72
+ <Duration>4.928</Duration>
73
+ <BitRate_Mode>VBR</BitRate_Mode>
74
+ <BitRate>31407</BitRate>
75
+ <Channels>2</Channels>
76
+ <ChannelPositions>Front: L R</ChannelPositions>
77
+ <ChannelLayout>L R</ChannelLayout>
78
+ <SamplesPerFrame>1024</SamplesPerFrame>
79
+ <SamplingRate>48000</SamplingRate>
80
+ <SamplingCount>236544</SamplingCount>
81
+ <FrameRate>46.875</FrameRate>
82
+ <FrameCount>231</FrameCount>
83
+ <Compression_Mode>Lossy</Compression_Mode>
84
+ <StreamSize>19347</StreamSize>
85
+ <StreamSize_Proportion>0.77774</StreamSize_Proportion>
86
+ <Encoded_Date>UTC 1970-01-01 00:00:00</Encoded_Date>
87
+ <Tagged_Date>UTC 1970-01-01 00:00:00</Tagged_Date>
88
+ </track>
89
+ </media>
90
+ </MediaInfo>
@@ -0,0 +1,90 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <MediaInfo
3
+ xmlns="https://mediaarea.net/mediainfo"
4
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5
+ xsi:schemaLocation="https://mediaarea.net/mediainfo https://mediaarea.net/mediainfo/mediainfo_2_0.xsd"
6
+ version="2.0">
7
+ <creatingLibrary version="18.05" url="https://mediaarea.net/MediaInfo">MediaInfoLib</creatingLibrary>
8
+ <media ref="file:///Bars_512kb.mp4">
9
+ <track type="General">
10
+ <VideoCount>1</VideoCount>
11
+ <AudioCount>1</AudioCount>
12
+ <FileExtension>mp4</FileExtension>
13
+ <Format>MPEG-4</Format>
14
+ <Format_Profile>Base Media</Format_Profile>
15
+ <CodecID>isom</CodecID>
16
+ <FileSize>24876</FileSize>
17
+ <Duration>4.928</Duration>
18
+ <OverallBitRate_Mode>VBR</OverallBitRate_Mode>
19
+ <OverallBitRate>40383</OverallBitRate>
20
+ <FrameRate>1.000</FrameRate>
21
+ <FrameCount>1</FrameCount>
22
+ <StreamSize>3216</StreamSize>
23
+ <HeaderSize>3208</HeaderSize>
24
+ <DataSize>21668</DataSize>
25
+ <FooterSize>0</FooterSize>
26
+ <IsStreamable>Yes</IsStreamable>
27
+ <Title>Bars - http://www.archive.org/details/ColorBarsWTone</Title>
28
+ <Movie>Bars - http://www.archive.org/details/ColorBarsWTone</Movie>
29
+ <Recorded_Date>2008</Recorded_Date>
30
+ <Encoded_Date>UTC 1970-01-01 00:00:00</Encoded_Date>
31
+ <Tagged_Date>UTC 2008-11-23 18:44:25</Tagged_Date>
32
+ <Encoded_Application>Lavf51.10.0</Encoded_Application>
33
+ <Comment>license: http://creativecommons.org/licenses/publicdomain/</Comment>
34
+ </track>
35
+ <track type="Video">
36
+ <StreamOrder>0</StreamOrder>
37
+ <ID>1</ID>
38
+ <Format>AVC</Format>
39
+ <Format_Profile>Baseline</Format_Profile>
40
+ <Format_Level>1.3</Format_Level>
41
+ <Format_Settings_CABAC>No</Format_Settings_CABAC>
42
+ <Format_Settings_RefFrames>1</Format_Settings_RefFrames>
43
+ <CodecID>avc1</CodecID>
44
+ <Duration>1.000</Duration>
45
+ <BitRate>18504</BitRate>
46
+ <Width>360</Width>
47
+ <Height>240</Height>
48
+ <Stored_Width>368</Stored_Width>
49
+ <Sampled_Width>360</Sampled_Width>
50
+ <Sampled_Height>240</Sampled_Height>
51
+ <PixelAspectRatio>1.000</PixelAspectRatio>
52
+ <DisplayAspectRatio>1.500</DisplayAspectRatio>
53
+ <Rotation>0.000</Rotation>
54
+ <FrameRate_Mode>CFR</FrameRate_Mode>
55
+ <FrameRate>1.000</FrameRate>
56
+ <FrameRate_Original>0.200</FrameRate_Original>
57
+ <FrameCount>1</FrameCount>
58
+ <ColorSpace>YUV</ColorSpace>
59
+ <ChromaSubsampling>4:2:0</ChromaSubsampling>
60
+ <BitDepth>8</BitDepth>
61
+ <ScanType>Progressive</ScanType>
62
+ <StreamSize>2313</StreamSize>
63
+ <Encoded_Date>UTC 1970-01-01 00:00:00</Encoded_Date>
64
+ <Tagged_Date>UTC 1970-01-01 00:00:00</Tagged_Date>
65
+ </track>
66
+ <track type="Audio">
67
+ <StreamOrder>1</StreamOrder>
68
+ <ID>2</ID>
69
+ <Format>AAC</Format>
70
+ <Format_Profile>LC</Format_Profile>
71
+ <CodecID>mp4a-40-2</CodecID>
72
+ <Duration>4.928</Duration>
73
+ <BitRate_Mode>VBR</BitRate_Mode>
74
+ <BitRate>31407</BitRate>
75
+ <Channels>2</Channels>
76
+ <ChannelPositions>Front: L R</ChannelPositions>
77
+ <ChannelLayout>L R</ChannelLayout>
78
+ <SamplesPerFrame>1024</SamplesPerFrame>
79
+ <SamplingRate>48000</SamplingRate>
80
+ <SamplingCount>236544</SamplingCount>
81
+ <FrameRate>46.875</FrameRate>
82
+ <FrameCount>231</FrameCount>
83
+ <Compression_Mode>Lossy</Compression_Mode>
84
+ <StreamSize>19347</StreamSize>
85
+ <StreamSize_Proportion>0.77774</StreamSize_Proportion>
86
+ <Encoded_Date>UTC 1970-01-01 00:00:00</Encoded_Date>
87
+ <Tagged_Date>UTC 1970-01-01 00:00:00</Tagged_Date>
88
+ </track>
89
+ </media>
90
+ </MediaInfo>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- require 'spec_helper'
2
+ require 'rails_helper'
3
3
  require 'shared_specs/engine_adapter_specs'
4
4
 
5
5
  describe ActiveEncode::EngineAdapters::FfmpegAdapter do
@@ -32,7 +32,9 @@ describe ActiveEncode::EngineAdapters::FfmpegAdapter do
32
32
  end
33
33
  let(:cancelling_job) do
34
34
  allow(Process).to receive(:kill).and_return(nil)
35
- find_encode 'running-id'
35
+ encode = find_encode 'running-id'
36
+ File.write "#{work_dir}/running-id/cancelled", ""
37
+ encode
36
38
  end
37
39
  let(:completed_job) { find_encode "completed-id" }
38
40
  let(:failed_job) { find_encode 'failed-id' }
@@ -107,6 +109,53 @@ describe ActiveEncode::EngineAdapters::FfmpegAdapter do
107
109
  expect(nonmedia_job.percent_complete).to be 1
108
110
  end
109
111
  end
112
+
113
+ context "input filename with spaces" do
114
+ let(:file_with_space) { "file://" + Rails.root.join('..', 'spec', 'fixtures', 'file with space.mp4').to_s }
115
+ let!(:create_space_job) { ActiveEncode::Base.create(file_with_space, outputs: [{ label: "low", ffmpeg_opt: "-s 640x480", extension: 'mp4' }]) }
116
+ let(:find_space_job) { ActiveEncode::Base.find create_space_job.id }
117
+
118
+ it "does not have errors" do
119
+ sleep 2
120
+ expect(find_space_job.errors).to be_empty
121
+ end
122
+
123
+ it "has the input technical metadata in a file" do
124
+ expect(File.read("#{work_dir}/#{create_space_job.id}/input_metadata")).not_to be_empty
125
+ end
126
+
127
+ it "has the pid in a file" do
128
+ expect(File.read("#{work_dir}/#{create_space_job.id}/pid")).not_to be_empty
129
+ end
130
+
131
+ context 'when uri encoded' do
132
+ let(:file_with_space) { URI.encode("file://" + Rails.root.join('..', 'spec', 'fixtures', 'file with space.mp4').to_s) }
133
+
134
+ it "does not have errors" do
135
+ sleep 2
136
+ expect(find_space_job.errors).to be_empty
137
+ end
138
+
139
+ it "has the input technical metadata in a file" do
140
+ expect(File.read("#{work_dir}/#{create_space_job.id}/input_metadata")).not_to be_empty
141
+ end
142
+
143
+ it "has the pid in a file" do
144
+ expect(File.read("#{work_dir}/#{create_space_job.id}/pid")).not_to be_empty
145
+ end
146
+ end
147
+ end
148
+
149
+ context 'when failed' do
150
+ subject { created_job }
151
+
152
+ before do
153
+ allow_any_instance_of(Object).to receive(:`).and_raise Errno::ENOENT
154
+ end
155
+
156
+ it { is_expected.to be_failed }
157
+ its(:errors) { is_expected.not_to be_empty }
158
+ end
110
159
  end
111
160
 
112
161
  describe "#find" do
@@ -124,5 +173,20 @@ describe ActiveEncode::EngineAdapters::FfmpegAdapter do
124
173
  expect(Process).to receive(:kill).with('SIGTERM', running_job.input.id.to_i)
125
174
  running_job.cancel!
126
175
  end
176
+
177
+ it "does not attempt to stop a non-running encode" do
178
+ expect(Process).not_to receive(:kill).with('SIGTERM', completed_job.input.id.to_i)
179
+ completed_job.cancel!
180
+ end
181
+
182
+ it "raises an error if the process can not be found" do
183
+ expect(Process).to receive(:kill).with('SIGTERM', running_job.input.id.to_i).and_raise(Errno::ESRCH)
184
+ expect { running_job.cancel! }.to raise_error(ActiveEncode::NotRunningError)
185
+ end
186
+
187
+ it "raises an error" do
188
+ expect(Process).to receive(:kill).with('SIGTERM', running_job.input.id.to_i).and_raise(Errno::EPERM)
189
+ expect { running_job.cancel! }.to raise_error(ActiveEncode::CancelError)
190
+ end
127
191
  end
128
192
  end
@@ -0,0 +1,151 @@
1
+ # frozen_string_literal: true
2
+ require 'rails_helper'
3
+ require 'shared_specs/engine_adapter_specs'
4
+
5
+ describe ActiveEncode::EngineAdapters::PassThroughAdapter do
6
+ around do |example|
7
+ ActiveEncode::Base.engine_adapter = :pass_through
8
+
9
+ Dir.mktmpdir do |dir|
10
+ @dir = dir
11
+ example.run
12
+ Dir.foreach(dir) do |e|
13
+ next if e == "." || e == ".."
14
+ FileUtils.rm_rf(File.join(dir, e))
15
+ end
16
+ end
17
+
18
+ ActiveEncode::Base.engine_adapter = :test
19
+ end
20
+
21
+ let!(:work_dir) { stub_const "ActiveEncode::EngineAdapters::PassThroughAdapter::WORK_DIR", @dir }
22
+ let(:file) { "file://" + Rails.root.join('..', 'spec', 'fixtures', 'fireworks.mp4').to_s }
23
+ let(:low_derivative) { "file://" + Rails.root.join('..', 'spec', 'fixtures', 'fireworks.low.mp4').to_s }
24
+ let(:created_job) do
25
+ ActiveEncode::Base.create(file, outputs: [{ label: 'low', url: low_derivative }])
26
+ end
27
+ let(:running_job) do
28
+ created_job
29
+ end
30
+ let(:canceled_job) do
31
+ find_encode 'cancelled-id'
32
+ end
33
+ let(:cancelling_job) do
34
+ find_encode 'running-id'
35
+ end
36
+ let(:completed_job) { find_encode "completed-id" }
37
+ let(:failed_job) { find_encode 'failed-id' }
38
+ let(:completed_tech_metadata) do
39
+ {
40
+ audio_bitrate: 171_030,
41
+ audio_codec: 'mp4a-40-2',
42
+ duration: 6315.0,
43
+ file_size: 199_160,
44
+ frame_rate: 23.719,
45
+ height: 110.0,
46
+ id: "completed-id",
47
+ url: "/home/pdinh/Downloads/videoshort.mp4",
48
+ video_bitrate: 74_477,
49
+ video_codec: 'avc1',
50
+ width: 200.0
51
+ }
52
+ end
53
+ let(:completed_output) { [{ id: "completed-id" }] }
54
+ let(:failed_tech_metadata) { {} }
55
+
56
+ it_behaves_like "an ActiveEncode::EngineAdapter"
57
+
58
+ def find_encode(id)
59
+ # Precreate ffmpeg output directory and files
60
+ FileUtils.copy_entry "spec/fixtures/pass_through/#{id}", "#{work_dir}/#{id}"
61
+
62
+ # Simulate that progress is modified later than other files
63
+ sleep 0.1
64
+ FileUtils.touch Dir.glob("#{work_dir}/#{id}/*.mp4")
65
+ touch_fixture(id, "completed")
66
+ touch_fixture(id, "cancelled")
67
+ touch_fixture(id, "error.log")
68
+
69
+ # Stub out system calls
70
+ allow_any_instance_of(ActiveEncode::EngineAdapters::PassThroughAdapter).to receive(:`).and_return(1234)
71
+
72
+ ActiveEncode::Base.find(id)
73
+ end
74
+
75
+ def touch_fixture(id, filename)
76
+ FileUtils.touch("#{work_dir}/#{id}/#{filename}") if File.exist? "#{work_dir}/#{id}/#{filename}"
77
+ end
78
+
79
+ describe "#create" do
80
+ subject { created_job }
81
+
82
+ it "creates a directory whose name is the encode id" do
83
+ expect(File).to exist("#{work_dir}/#{subject.id}")
84
+ end
85
+
86
+ context "input file exists" do
87
+ it "has the input technical metadata in a file" do
88
+ expect(File.read("#{work_dir}/#{subject.id}/input_metadata")).not_to be_empty
89
+ end
90
+ end
91
+
92
+ context "input file doesn't exist" do
93
+ let(:missing_file) { "file:///a_bogus_file.mp4" }
94
+ let(:missing_job) { ActiveEncode::Base.create(missing_file, outputs: [{ label: "low", url: 'mp4' }]) }
95
+
96
+ it "returns the encode with correct error" do
97
+ expect(missing_job.errors).to include("#{missing_file} does not exist or is not accessible")
98
+ expect(missing_job.percent_complete).to be 1
99
+ end
100
+ end
101
+
102
+ context "input file is not media" do
103
+ let(:nonmedia_file) { "file://" + Rails.root.join('Gemfile').to_s }
104
+ let(:nonmedia_job) { ActiveEncode::Base.create(nonmedia_file, outputs: [{ label: "low", url: nonmedia_file }]) }
105
+
106
+ it "returns the encode with correct error" do
107
+ expect(nonmedia_job.errors).to include("Error inspecting input: #{nonmedia_file}")
108
+ expect(nonmedia_job.percent_complete).to be 1
109
+ end
110
+ end
111
+
112
+ context "input filename with spaces" do
113
+ let(:file_with_space) { "file://" + Rails.root.join('..', 'spec', 'fixtures', 'file with space.mp4').to_s }
114
+ let(:file_with_space_derivative) { "file://" + Rails.root.join('..', 'spec', 'fixtures', 'file with space.low.mp4').to_s }
115
+ let!(:create_space_job) { ActiveEncode::Base.create(file_with_space, outputs: [{ label: "low", url: file_with_space_derivative }]) }
116
+ let(:find_space_job) { ActiveEncode::Base.find create_space_job.id }
117
+
118
+ it "does not have errors" do
119
+ expect(find_space_job.errors).to be_empty
120
+ end
121
+
122
+ it "has the input technical metadata in a file" do
123
+ expect(File.read("#{work_dir}/#{create_space_job.id}/input_metadata")).not_to be_empty
124
+ end
125
+
126
+ context 'when uri encoded' do
127
+ let(:file_with_space) { URI.encode("file://" + Rails.root.join('..', 'spec', 'fixtures', 'file with space.mp4').to_s) }
128
+ let(:file_with_space_derivative) { URI.encode("file://" + Rails.root.join('..', 'spec', 'fixtures', 'file with space.low.mp4').to_s) }
129
+
130
+ it "does not have errors" do
131
+ expect(find_space_job.errors).to be_empty
132
+ end
133
+
134
+ it "has the input technical metadata in a file" do
135
+ expect(File.read("#{work_dir}/#{create_space_job.id}/input_metadata")).not_to be_empty
136
+ end
137
+ end
138
+ end
139
+
140
+ context 'when failed' do
141
+ subject { created_job }
142
+
143
+ before do
144
+ allow_any_instance_of(Object).to receive(:`).and_raise Errno::ENOENT
145
+ end
146
+
147
+ it { is_expected.to be_failed }
148
+ its(:errors) { is_expected.not_to be_empty }
149
+ end
150
+ end
151
+ end
@@ -50,12 +50,12 @@ RSpec.shared_examples 'an ActiveEncode::EngineAdapter' do |*_flags|
50
50
  it 'returns an ActiveEncode::Base object' do
51
51
  expect(subject.class).to be ActiveEncode::Base
52
52
  end
53
- its(:id) { is_expected.to eq 'running-id' }
53
+ its(:id) { is_expected.to be_present }
54
54
  it { is_expected.to be_running }
55
55
  its(:percent_complete) { is_expected.to be > 0 }
56
56
  its(:errors) { is_expected.to be_empty }
57
57
  its(:created_at) { is_expected.to be_kind_of Time }
58
- its(:updated_at) { is_expected.to be > subject.created_at }
58
+ its(:updated_at) { is_expected.to be >= subject.created_at }
59
59
 
60
60
  it 'input is a valid ActiveEncode::Input object' do
61
61
  expect(subject.input).to be_a ActiveEncode::Input
@@ -77,7 +77,7 @@ RSpec.shared_examples 'an ActiveEncode::EngineAdapter' do |*_flags|
77
77
  it 'returns an ActiveEncode::Base object' do
78
78
  expect(subject.class).to be ActiveEncode::Base
79
79
  end
80
- its(:id) { is_expected.to eq 'cancelled-id' }
80
+ its(:id) { is_expected.to be_present }
81
81
  it { is_expected.to be_cancelled }
82
82
  its(:percent_complete) { is_expected.to be > 0 }
83
83
  its(:errors) { is_expected.to be_empty }
@@ -104,7 +104,7 @@ RSpec.shared_examples 'an ActiveEncode::EngineAdapter' do |*_flags|
104
104
  it 'returns an ActiveEncode::Base object' do
105
105
  expect(subject.class).to be ActiveEncode::Base
106
106
  end
107
- its(:id) { is_expected.to eq 'completed-id' }
107
+ its(:id) { is_expected.to be_present }
108
108
  it { is_expected.to be_completed }
109
109
  its(:percent_complete) { is_expected.to eq 100 }
110
110
  its(:errors) { is_expected.to be_empty }
@@ -142,7 +142,7 @@ RSpec.shared_examples 'an ActiveEncode::EngineAdapter' do |*_flags|
142
142
  it 'returns an ActiveEncode::Base object' do
143
143
  expect(subject.class).to be ActiveEncode::Base
144
144
  end
145
- its(:id) { is_expected.to eq 'failed-id' }
145
+ its(:id) { is_expected.to be_present }
146
146
  it { is_expected.to be_failed }
147
147
  its(:percent_complete) { is_expected.to be > 0 }
148
148
  its(:errors) { is_expected.not_to be_empty }
@@ -201,12 +201,11 @@ RSpec.shared_examples 'an ActiveEncode::EngineAdapter' do |*_flags|
201
201
  it 'returns an ActiveEncode::Base object' do
202
202
  expect(subject.class).to be ActiveEncode::Base
203
203
  end
204
- its(:id) { is_expected.to eq 'running-id' }
205
- it { is_expected.to be_running }
204
+ its(:id) { is_expected.to be_present }
206
205
  its(:percent_complete) { is_expected.to be > 0 }
207
206
  its(:errors) { is_expected.to be_empty }
208
207
  its(:created_at) { is_expected.to be_kind_of Time }
209
- its(:updated_at) { is_expected.to be > subject.created_at }
208
+ its(:updated_at) { is_expected.to be >= subject.created_at }
210
209
 
211
210
  it 'input is a valid ActiveEncode::Input object' do
212
211
  expect(subject.input).to be_a ActiveEncode::Input