active_encode 0.1.1 → 0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +3 -2
  4. data/Gemfile +35 -0
  5. data/README.md +15 -14
  6. data/Rakefile +5 -10
  7. data/active_encode.gemspec +8 -5
  8. data/app/jobs/active_encode/polling_job.rb +20 -0
  9. data/app/models/active_encode/encode_record.rb +5 -0
  10. data/db/migrate/20180822021048_create_active_encode_encode_records.rb +13 -0
  11. data/lib/active_encode.rb +1 -0
  12. data/lib/active_encode/base.rb +6 -2
  13. data/lib/active_encode/callbacks.rb +18 -35
  14. data/lib/active_encode/core.rb +64 -20
  15. data/lib/active_encode/engine.rb +7 -0
  16. data/lib/active_encode/engine_adapter.rb +2 -2
  17. data/lib/active_encode/engine_adapters/active_job_adapter.rb +7 -3
  18. data/lib/active_encode/engine_adapters/elastic_transcoder_adapter.rb +15 -15
  19. data/lib/active_encode/engine_adapters/inline_adapter.rb +6 -1
  20. data/lib/active_encode/engine_adapters/matterhorn_adapter.rb +18 -18
  21. data/lib/active_encode/engine_adapters/shingoncoder_adapter.rb +13 -9
  22. data/lib/active_encode/engine_adapters/test_adapter.rb +19 -12
  23. data/lib/active_encode/engine_adapters/zencoder_adapter.rb +10 -10
  24. data/lib/active_encode/global_id.rb +16 -0
  25. data/lib/active_encode/input.rb +9 -0
  26. data/lib/active_encode/output.rb +9 -0
  27. data/lib/active_encode/persistence.rb +45 -0
  28. data/lib/active_encode/polling.rb +24 -0
  29. data/lib/active_encode/status.rb +2 -6
  30. data/lib/active_encode/technical_metadata.rb +16 -1
  31. data/lib/active_encode/version.rb +1 -1
  32. data/spec/fixtures/elastic_transcoder/job_canceled.json +1 -1
  33. data/spec/fixtures/elastic_transcoder/job_completed.json +1 -1
  34. data/spec/fixtures/elastic_transcoder/job_created.json +1 -1
  35. data/spec/fixtures/elastic_transcoder/job_failed.json +1 -1
  36. data/spec/fixtures/elastic_transcoder/job_progressing.json +1 -1
  37. data/spec/integration/elastic_transcoder_adapter_spec.rb +87 -167
  38. data/spec/integration/matterhorn_adapter_spec.rb +34 -79
  39. data/spec/integration/shingoncoder_adapter_spec.rb +1 -1
  40. data/spec/integration/zencoder_adapter_spec.rb +1 -1
  41. data/spec/rails_helper.rb +22 -0
  42. data/spec/shared_specs/engine_adapter_specs.rb +124 -0
  43. data/spec/test_app_templates/lib/generators/test_app_generator.rb +15 -0
  44. data/spec/units/callbacks_spec.rb +16 -17
  45. data/spec/units/core_spec.rb +121 -2
  46. data/spec/units/engine_adapter_spec.rb +0 -12
  47. data/spec/units/global_id_spec.rb +49 -0
  48. data/spec/units/input_spec.rb +12 -0
  49. data/spec/units/output_spec.rb +12 -0
  50. data/spec/units/persistence_spec.rb +57 -0
  51. data/spec/units/polling_job_spec.rb +86 -0
  52. data/spec/units/polling_spec.rb +22 -0
  53. data/spec/units/status_spec.rb +21 -2
  54. metadata +89 -20
@@ -7,7 +7,7 @@ describe ActiveEncode::EngineAdapters::ShingoncoderAdapter do
7
7
  ActiveEncode::Base.engine_adapter = :shingoncoder
8
8
  end
9
9
  after(:all) do
10
- ActiveEncode::Base.engine_adapter = :inline
10
+ ActiveEncode::Base.engine_adapter = :test
11
11
  end
12
12
 
13
13
  let(:create_response) { Shingoncoder::Response.new(body: JSON.parse(File.read('spec/fixtures/zencoder/job_create.json'))) }
@@ -7,7 +7,7 @@ describe ActiveEncode::EngineAdapters::ZencoderAdapter do
7
7
  ActiveEncode::Base.engine_adapter = :zencoder
8
8
  end
9
9
  after(:all) do
10
- ActiveEncode::Base.engine_adapter = :inline
10
+ ActiveEncode::Base.engine_adapter = :test
11
11
  end
12
12
 
13
13
  let(:create_response) { Zencoder::Response.new(body: JSON.parse(File.read('spec/fixtures/zencoder/job_create.json'))) }
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ require 'engine_cart'
4
+ EngineCart.load_application!
5
+
6
+ require 'rspec/rails'
7
+ ActiveJob::Base.queue_adapter = :test
8
+
9
+ require 'database_cleaner'
10
+
11
+ RSpec.configure do |config|
12
+ config.before do |example|
13
+ if example.metadata[:db_clean]
14
+ DatabaseCleaner.clean_with(:truncation)
15
+ DatabaseCleaner.strategy = :truncation
16
+ end
17
+ end
18
+
19
+ config.after do |example|
20
+ DatabaseCleaner.clean if example.metadata[:db_clean]
21
+ end
22
+ end
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+ RSpec.shared_examples 'an ActiveEncode::EngineAdapter' do |*_flags|
3
+ before do
4
+ raise 'adapter must be set with `let(:created_job)`' unless defined? created_job
5
+ raise 'adapter must be set with `let(:running_job)`' unless defined? running_job
6
+ raise 'adapter must be set with `let(:canceled_job)`' unless defined? canceled_job
7
+ raise 'adapter must be set with `let(:completed_job)`' unless defined? completed_job
8
+ raise 'adapter must be set with `let(:failed_job)`' unless defined? failed_job
9
+ end
10
+
11
+ it { is_expected.to respond_to :create }
12
+ it { is_expected.to respond_to :find }
13
+ it { is_expected.to respond_to :cancel }
14
+
15
+ describe "#create" do
16
+ subject { created_job }
17
+
18
+ it { is_expected.to be_a ActiveEncode::Base }
19
+ its(:id) { is_expected.not_to be_empty }
20
+ it { is_expected.to be_running }
21
+ its(:current_operations) { is_expected.to be_empty }
22
+ its(:percent_complete) { is_expected.to be < 100 }
23
+ its(:errors) { is_expected.to be_empty }
24
+ its(:created_at) { is_expected.to be_kind_of Time }
25
+ its(:updated_at) { is_expected.to be_nil }
26
+ its(:finished_at) { is_expected.to be_nil }
27
+ its(:tech_metadata) { is_expected.to be_empty }
28
+ end
29
+
30
+ describe "#find" do
31
+ context "a running encode" do
32
+ subject { running_job }
33
+
34
+ it 'returns an ActiveEncode::Base object' do
35
+ expect(subject.class).to be ActiveEncode::Base
36
+ end
37
+ its(:id) { is_expected.to eq 'running-id' }
38
+ it { is_expected.to be_running }
39
+ its(:percent_complete) { is_expected.to be > 0 }
40
+ its(:errors) { is_expected.to be_empty }
41
+ its(:created_at) { is_expected.to be_kind_of Time }
42
+ its(:updated_at) { is_expected.to be > subject.created_at }
43
+ its(:finished_at) { is_expected.to be_nil }
44
+ end
45
+
46
+ context "a cancelled encode" do
47
+ subject { canceled_job }
48
+
49
+ it 'returns an ActiveEncode::Base object' do
50
+ expect(subject.class).to be ActiveEncode::Base
51
+ end
52
+ its(:id) { is_expected.to eq 'cancelled-id' }
53
+ it { is_expected.to be_cancelled }
54
+ its(:percent_complete) { is_expected.to be > 0 }
55
+ its(:errors) { is_expected.to be_empty }
56
+ its(:created_at) { is_expected.to be_kind_of Time }
57
+ its(:finished_at) { is_expected.to be >= subject.created_at }
58
+ its(:tech_metadata) { is_expected.to be_empty }
59
+ end
60
+
61
+ context "a completed encode" do
62
+ subject { completed_job }
63
+
64
+ it 'returns an ActiveEncode::Base object' do
65
+ expect(subject.class).to be ActiveEncode::Base
66
+ end
67
+ its(:id) { is_expected.to eq 'completed-id' }
68
+ it { is_expected.to be_completed }
69
+ its(:output) { is_expected.to eq completed_output }
70
+ its(:percent_complete) { is_expected.to eq 100 }
71
+ its(:errors) { is_expected.to be_empty }
72
+ its(:created_at) { is_expected.to be_kind_of Time }
73
+ its(:updated_at) { is_expected.to be > subject.created_at }
74
+ its(:finished_at) { is_expected.to be >= subject.updated_at }
75
+ its(:tech_metadata) { is_expected.to include completed_tech_metadata }
76
+ end
77
+
78
+ context "a failed encode" do
79
+ subject { failed_job }
80
+
81
+ it 'returns an ActiveEncode::Base object' do
82
+ expect(subject.class).to be ActiveEncode::Base
83
+ end
84
+ its(:id) { is_expected.to eq 'failed-id' }
85
+ it { is_expected.to be_failed }
86
+ its(:percent_complete) { is_expected.to be > 0 }
87
+ its(:errors) { is_expected.not_to be_empty }
88
+ its(:created_at) { is_expected.to be_kind_of Time }
89
+ its(:updated_at) { is_expected.to be > subject.created_at }
90
+ its(:finished_at) { is_expected.to be >= subject.updated_at }
91
+ its(:tech_metadata) { is_expected.to include failed_tech_metadata }
92
+ end
93
+ end
94
+
95
+ describe "#cancel!" do
96
+ subject { cancelling_job.cancel! }
97
+
98
+ it 'returns an ActiveEncode::Base object' do
99
+ expect(subject.class).to be ActiveEncode::Base
100
+ end
101
+ its(:id) { is_expected.to eq 'cancelled-id' }
102
+ it { is_expected.to be_cancelled }
103
+ its(:percent_complete) { is_expected.to be > 0 }
104
+ its(:errors) { is_expected.to be_empty }
105
+ its(:created_at) { is_expected.to be_kind_of Time }
106
+ its(:finished_at) { is_expected.to be >= subject.created_at }
107
+ its(:tech_metadata) { is_expected.to be_empty }
108
+ end
109
+
110
+ describe "reload" do
111
+ subject { running_job.reload }
112
+
113
+ it 'returns an ActiveEncode::Base object' do
114
+ expect(subject.class).to be ActiveEncode::Base
115
+ end
116
+ its(:id) { is_expected.to eq 'running-id' }
117
+ it { is_expected.to be_running }
118
+ its(:percent_complete) { is_expected.to be > 0 }
119
+ its(:errors) { is_expected.to be_empty }
120
+ its(:created_at) { is_expected.to be_kind_of Time }
121
+ its(:updated_at) { is_expected.to be > subject.created_at }
122
+ its(:finished_at) { is_expected.to be_nil }
123
+ end
124
+ end
@@ -0,0 +1,15 @@
1
+ require 'rails/generators'
2
+
3
+ class TestAppGenerator < Rails::Generators::Base
4
+ source_root "./spec/test_app_templates"
5
+
6
+ # if you need to generate any additional configuration
7
+ # into the test app, this generator will be run immediately
8
+ # after setting up the application
9
+
10
+ def install_engine
11
+ generate 'active_encode:install'
12
+ rake 'active_encode:install:migrations'
13
+ end
14
+ end
15
+
@@ -3,15 +3,16 @@ require 'spec_helper'
3
3
  describe ActiveEncode::Callbacks do
4
4
  before do
5
5
  class CallbackEncode < ActiveEncode::Base
6
+ after_find ->(encode) { encode.history << "CallbackEncode ran after_find" }
7
+
8
+ after_reload ->(encode) { encode.history << "CallbackEncode ran after_reload" }
9
+
6
10
  before_create ->(encode) { encode.history << "CallbackEncode ran before_create" }
7
11
  after_create ->(encode) { encode.history << "CallbackEncode ran after_create" }
8
12
 
9
13
  before_cancel ->(encode) { encode.history << "CallbackEncode ran before_cancel" }
10
14
  after_cancel ->(encode) { encode.history << "CallbackEncode ran after_cancel" }
11
15
 
12
- before_purge ->(encode) { encode.history << "CallbackEncode ran before_purge" }
13
- after_purge ->(encode) { encode.history << "CallbackEncode ran after_purge" }
14
-
15
16
  around_create do |encode, block|
16
17
  encode.history << "CallbackEncode ran around_create_start"
17
18
  block.call
@@ -24,12 +25,6 @@ describe ActiveEncode::Callbacks do
24
25
  encode.history << "CallbackEncode ran around_cancel_stop"
25
26
  end
26
27
 
27
- around_purge do |encode, block|
28
- encode.history << "CallbackEncode ran around_purge_start"
29
- block.call
30
- encode.history << "CallbackEncode ran around_purge_stop"
31
- end
32
-
33
28
  def history
34
29
  @history ||= []
35
30
  end
@@ -40,6 +35,18 @@ describe ActiveEncode::Callbacks do
40
35
  Object.send(:remove_const, :CallbackEncode)
41
36
  end
42
37
 
38
+ describe 'find callback' do
39
+ let(:encode) { CallbackEncode.create("sample.mp4") }
40
+ subject { CallbackEncode.find(encode.id).history }
41
+ it { is_expected.to include("CallbackEncode ran after_find") }
42
+ end
43
+
44
+ describe 'reload callback' do
45
+ let(:encode) { CallbackEncode.create("sample.mp4") }
46
+ subject { encode.reload.history }
47
+ it { is_expected.to include("CallbackEncode ran after_reload") }
48
+ end
49
+
43
50
  describe 'create callbacks' do
44
51
  subject { CallbackEncode.create("sample.mp4").history }
45
52
  it { is_expected.to include("CallbackEncode ran before_create") }
@@ -55,12 +62,4 @@ describe ActiveEncode::Callbacks do
55
62
  it { is_expected.to include("CallbackEncode ran around_cancel_start") }
56
63
  it { is_expected.to include("CallbackEncode ran around_cancel_stop") }
57
64
  end
58
-
59
- describe 'purge callbacks' do
60
- subject { CallbackEncode.create("sample.mp4").purge!.history }
61
- it { is_expected.to include("CallbackEncode ran before_purge") }
62
- it { is_expected.to include("CallbackEncode ran after_purge") }
63
- it { is_expected.to include("CallbackEncode ran around_purge_start") }
64
- it { is_expected.to include("CallbackEncode ran around_purge_stop") }
65
- end
66
65
  end
@@ -1,9 +1,128 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe ActiveEncode::Core do
4
+ before do
5
+ class CustomEncode < ActiveEncode::Base
6
+ end
7
+ end
8
+ after do
9
+ Object.send(:remove_const, :CustomEncode)
10
+ end
11
+
12
+ let(:encode_class) { ActiveEncode::Base }
13
+
14
+ describe 'attributes' do
15
+ subject { encode_class.new(nil) }
16
+
17
+ it { is_expected.to respond_to(:id, :input, :output, :options, :percent_complete, :current_operations) }
18
+
19
+ context 'with an ActiveEncode::Base subclass' do
20
+ let(:encode_class) { CustomEncode }
21
+
22
+ it { is_expected.to respond_to(:id, :input, :output, :options, :percent_complete, :current_operations) }
23
+ end
24
+ end
25
+
4
26
  describe 'find' do
5
- it "raises NotFound when no id is supplied" do
6
- expect { ActiveEncode::Base.find(nil) }.to raise_error(ArgumentError)
27
+ let(:id) { encode_class.create(nil).id }
28
+ subject { encode_class.find(id) }
29
+
30
+ it { is_expected.to be_a encode_class }
31
+ its(:id) { is_expected.to eq id }
32
+
33
+ context 'with no id' do
34
+ let(:id) { nil }
35
+
36
+ it 'raises an error' do
37
+ expect { subject }.to raise_error(ArgumentError)
38
+ end
39
+ end
40
+
41
+ context 'with an ActiveEncode::Base subclass' do
42
+ let(:encode_class) { CustomEncode }
43
+
44
+ it { is_expected.to be_a encode_class }
45
+ its(:id) { is_expected.to eq id }
46
+
47
+ context 'casting' do
48
+ let(:id) { ActiveEncode::Base.create(nil).id }
49
+
50
+ it { is_expected.to be_a encode_class }
51
+ its(:id) { is_expected.to eq id }
52
+ end
53
+ end
54
+ end
55
+
56
+ describe 'create' do
57
+ subject { encode_class.create(nil) }
58
+
59
+ it { is_expected.to be_a encode_class }
60
+ its(:id) { is_expected.not_to be nil }
61
+ its(:state) { is_expected.not_to be nil }
62
+
63
+ context 'with an ActiveEncode::Base subclass' do
64
+ let(:encode_class) { CustomEncode }
65
+
66
+ it { is_expected.to be_a encode_class }
67
+ its(:id) { is_expected.not_to be nil }
68
+ its(:state) { is_expected.not_to be nil }
69
+ end
70
+ end
71
+
72
+ describe '#create!' do
73
+ let(:encode) { encode_class.new(nil) }
74
+ subject { encode.create! }
75
+
76
+ it { is_expected.to equal encode }
77
+ it { is_expected.to be_a encode_class }
78
+ its(:id) { is_expected.not_to be nil }
79
+ its(:state) { is_expected.not_to be nil }
80
+
81
+ context 'with an ActiveEncode::Base subclass' do
82
+ let(:encode_class) { CustomEncode }
83
+
84
+ it { is_expected.to equal encode }
85
+ it { is_expected.to be_a encode_class }
86
+ its(:id) { is_expected.not_to be nil }
87
+ its(:state) { is_expected.not_to be nil }
88
+ end
89
+ end
90
+
91
+ describe '#cancel!' do
92
+ let(:encode) { encode_class.create(nil) }
93
+ subject { encode.cancel! }
94
+
95
+ it { is_expected.to equal encode }
96
+ it { is_expected.to be_a encode_class }
97
+ its(:id) { is_expected.not_to be nil }
98
+ it { is_expected.to be_cancelled }
99
+
100
+ context 'with an ActiveEncode::Base subclass' do
101
+ let(:encode_class) { CustomEncode }
102
+
103
+ it { is_expected.to equal encode }
104
+ it { is_expected.to be_a encode_class }
105
+ its(:id) { is_expected.not_to be nil }
106
+ it { is_expected.to be_cancelled }
107
+ end
108
+ end
109
+
110
+ describe '#reload' do
111
+ let(:encode) { encode_class.create(nil) }
112
+ subject { encode.reload }
113
+
114
+ it { is_expected.to equal encode }
115
+ it { is_expected.to be_a encode_class }
116
+ its(:id) { is_expected.not_to be nil }
117
+ its(:state) { is_expected.not_to be nil }
118
+
119
+ context 'with an ActiveEncode::Base subclass' do
120
+ let(:encode_class) { CustomEncode }
121
+
122
+ it { is_expected.to equal encode }
123
+ it { is_expected.to be_a encode_class }
124
+ its(:id) { is_expected.not_to be nil }
125
+ its(:state) { is_expected.not_to be nil }
7
126
  end
8
127
  end
9
128
  end
@@ -9,13 +9,7 @@ describe ActiveEncode::EngineAdapter do
9
9
 
10
10
  def find(_, _ = {}); end
11
11
 
12
- def list(*); end
13
-
14
12
  def cancel(_encode); end
15
-
16
- def purge(_encode); end
17
-
18
- def remove_output(_encode, _output_id); end
19
13
  end
20
14
 
21
15
  class StubTwoAdapter
@@ -23,13 +17,7 @@ describe ActiveEncode::EngineAdapter do
23
17
 
24
18
  def find(_id, _opts = {}); end
25
19
 
26
- def list(*); end
27
-
28
20
  def cancel(_encode); end
29
-
30
- def purge(_encode); end
31
-
32
- def remove_output(_encode, _output_id); end
33
21
  end
34
22
  end
35
23
  end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActiveEncode::GlobalID do
4
+ before do
5
+ class CustomEncode < ActiveEncode::Base
6
+ end
7
+ end
8
+
9
+ after do
10
+ Object.send(:remove_const, :CustomEncode)
11
+ end
12
+
13
+ describe '#to_global_id' do
14
+ let(:encode_class) { ActiveEncode::Base }
15
+ let(:encode) { encode_class.create(nil) }
16
+ subject { encode.to_global_id }
17
+
18
+ it { is_expected.to be_a GlobalID }
19
+ its(:model_class) { is_expected.to eq encode_class }
20
+ its(:model_id) { is_expected.to eq encode.id }
21
+ its(:app) { is_expected.to eq 'ActiveEncode' }
22
+
23
+ context 'with an ActiveEncode::Base subclass' do
24
+ let(:encode_class) { CustomEncode }
25
+
26
+ it { is_expected.to be_a GlobalID }
27
+ its(:model_class) { is_expected.to eq encode_class }
28
+ its(:model_id) { is_expected.to eq encode.id }
29
+ its(:app) { is_expected.to eq 'ActiveEncode' }
30
+ end
31
+ end
32
+
33
+ describe 'GlobalID::Locator#locate' do
34
+ let(:encode_class) { ActiveEncode::Base }
35
+ let(:encode) { encode_class.create(nil) }
36
+ let(:global_id) { encode.to_global_id }
37
+ subject { GlobalID::Locator.locate(global_id) }
38
+
39
+ it { is_expected.to be_a encode_class }
40
+ its(:id) { is_expected.to eq encode.id }
41
+
42
+ context 'with an ActiveEncode::Base subclass' do
43
+ let(:encode_class) { CustomEncode }
44
+
45
+ it { is_expected.to be_a encode_class }
46
+ its(:id) { is_expected.to eq encode.id }
47
+ end
48
+ end
49
+ end