chili_videos 0.1.0

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 (66) hide show
  1. data.tar.gz.sig +1 -0
  2. data/.autotest +5 -0
  3. data/Gemfile +13 -0
  4. data/Gemfile.lock +33 -0
  5. data/History.txt +4 -0
  6. data/LICENSE +20 -0
  7. data/Manifest.txt +63 -0
  8. data/README.md +169 -0
  9. data/Rakefile +45 -0
  10. data/app/controllers/videos_controller.rb +72 -0
  11. data/app/helpers/videos_helper.rb +34 -0
  12. data/app/models/assembly.rb +62 -0
  13. data/app/models/assembly_observer.rb +6 -0
  14. data/app/models/assembly_processor.rb +16 -0
  15. data/app/models/video.rb +24 -0
  16. data/app/views/settings/_settings.html.erb +13 -0
  17. data/app/views/videos/edit.html.erb +32 -0
  18. data/app/views/videos/index.html.erb +37 -0
  19. data/app/views/videos/new.html.erb +41 -0
  20. data/app/views/videos/plugin_not_configured.html.erb +6 -0
  21. data/app/views/videos/show.html.erb +40 -0
  22. data/app/views/videos/upload_complete.html.erb +7 -0
  23. data/assets/player.swf +0 -0
  24. data/assets/readme.html +84 -0
  25. data/assets/stylesheets/forms.css +7 -0
  26. data/assets/stylesheets/videos.css +76 -0
  27. data/assets/swfobject.js +8 -0
  28. data/assets/yt.swf +0 -0
  29. data/autotest/discover.rb +4 -0
  30. data/bin/delayed_job +23 -0
  31. data/config/locales/en.yml +15 -0
  32. data/config/routes.rb +3 -0
  33. data/db/migrate/20110301025054_create_videos.rb +15 -0
  34. data/db/migrate/20110309060901_create_assemblies.rb +14 -0
  35. data/db/migrate/20110314022354_create_delayed_jobs.rb +21 -0
  36. data/db/migrate/20110402043115_create_slugs.rb +18 -0
  37. data/db/migrate/20110402053931_add_slug_cache_to_videos.rb +11 -0
  38. data/init.rb +63 -0
  39. data/lang/en.yml +16 -0
  40. data/lib/chili_videos.rb +18 -0
  41. data/lib/chili_videos/config.rb +40 -0
  42. data/lib/chili_videos/error.rb +5 -0
  43. data/lib/tasks/chili_videos_tasks.rb +112 -0
  44. data/lib/tasks/contributor_tasks.rb +64 -0
  45. data/lib/tasks/delayed_job.rake +6 -0
  46. data/lib/tasks/friendly_id.rake +19 -0
  47. data/lib/video_project_patch.rb +10 -0
  48. data/lib/video_user_patch.rb +10 -0
  49. data/lib/video_version_patch.rb +9 -0
  50. data/rails/delayed_job +25 -0
  51. data/rails/init.rb +1 -0
  52. data/test/fixtures/incomplete_assembly.json +9 -0
  53. data/test/fixtures/single_video_processed_assembly.json +9 -0
  54. data/test/fixtures/standard_transloadit_response.json +6 -0
  55. data/test/functional/videos_controller_test.rb +232 -0
  56. data/test/integration/project_video_list_test.rb +104 -0
  57. data/test/integration/project_video_uploading_test.rb +56 -0
  58. data/test/integration/viewing_project_video_test.rb +74 -0
  59. data/test/test_helper.rb +77 -0
  60. data/test/unit/assembly_processor_test.rb +57 -0
  61. data/test/unit/assembly_test.rb +95 -0
  62. data/test/unit/chili_video_plugin/config_test.rb +49 -0
  63. data/test/unit/chili_video_plugin_test.rb +30 -0
  64. data/test/unit/video_test.rb +26 -0
  65. metadata +279 -0
  66. metadata.gz.sig +0 -0
@@ -0,0 +1,56 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class ProjectVideoUploadingTest < ActionController::IntegrationTest
4
+ def setup
5
+ @user = User.generate!(:login => 'existing', :password => 'existing', :password_confirmation => 'existing')
6
+ @project = Project.generate!.reload
7
+
8
+ User.add_to_project(@user, @project, Role.generate!(:permissions => [:view_video_list, :add_video]))
9
+
10
+ login_as
11
+ end
12
+
13
+ def plugin_settings(api_key, workflow)
14
+ Setting["plugin_chili_videos"] = HashWithIndifferentAccess.new({:transloadit_api_key => api_key, :transloadit_workflow => workflow})
15
+ end
16
+
17
+
18
+ context "Uploading a video" do
19
+ context "when the plugin is set up correctly" do
20
+ setup do
21
+ plugin_settings('api-key', 'workflow')
22
+ end
23
+
24
+ should "set the 'redirect_url' form param to the 'upload_complete' url" do
25
+ visit(new_project_video_path(@project))
26
+ proper_redirect_url = "&quot;redirect_url&quot;:&quot;http://www.example.com/projects/#{@project.to_param}/videos/upload_complete&quot;"
27
+ assert_match proper_redirect_url, response.body
28
+ end
29
+
30
+ should "set the 'template_id' form param to the setting stored in the plugin settings" do
31
+ visit(new_project_video_path(@project))
32
+ escaped_template_id = "&quot;template_id&quot;:&quot;workflow&quot;"
33
+ assert_match escaped_template_id, response.body
34
+ end
35
+
36
+ should "set the 'auth_key' form param to the setting stored in the plugin settings" do
37
+ visit(new_project_video_path(@project))
38
+ escaped_api_key = "&quot;key&quot;:&quot;api-key&quot;"
39
+ assert_match escaped_api_key, response.body
40
+ end
41
+ end
42
+
43
+ context "when the plugin does not have either the Transload.it workflow or API key stored in the plugin settings" do
44
+ setup do
45
+ plugin_settings('','')
46
+ end
47
+
48
+ should "display a message telling the user to set up the plugin on the plugin administration page" do
49
+ visit(new_project_video_path(@project))
50
+ within("p.warning") do
51
+ assert_have_selector('a', :href => '/settings/plugin/chili_videos')
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,74 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class ViewingProjectVideoTest < ActionController::IntegrationTest
4
+ include VideosHelper
5
+
6
+ def setup
7
+ ChiliVideos::Config.update(:api_key => 'api-key', :workflow => 'wf')
8
+
9
+ @user = User.generate!(:login => 'existing', :password => 'existing', :password_confirmation => 'existing', :admin => true)
10
+ @project = Project.generate!.reload
11
+ User.add_to_project(@user, @project, Role.generate!(:permissions => [:view_video_list, :add_video, :view_specific_video]))
12
+ login_as
13
+ end
14
+
15
+ context "Viewing a specific video associated with a Project by clicking the video link" do
16
+ context "when the specified video is not associated with the project" do
17
+ setup do
18
+ Video.destroy_all
19
+ visit(project_video_path(@project, 'nonexistant-video'))
20
+ end
21
+
22
+ should "display an error message to the user" do
23
+ assert_have_selector("div.error")
24
+ end
25
+ end
26
+
27
+ context "when the requested video has been associated with the project" do
28
+ setup do
29
+ @video = Video.create!(:title => "Video 1", :description => "Description...", :url => "http://some-url-here.com/", :project_id => @project.id, :user_id => @user.id)
30
+ visit(project_video_path(@project, @video))
31
+ end
32
+
33
+ should "include the code to embed the video in another project page with the standard size" do
34
+ within("div.video") do
35
+ assert_have_selector("input.embed.standard[value='#{video_embed_macro_markup(@video)}']")
36
+ end
37
+ end
38
+
39
+ should "have a link to delete the video" do
40
+ within("div.contextual") do
41
+ assert_have_selector("a[class~='video-del'][href='#{project_video_path(@project, @video)}']")
42
+ end
43
+ end
44
+
45
+ should "have a link to edit the video" do
46
+ within("div.contextual") do
47
+ assert_have_selector("a[class~='video-edit'][href='#{edit_project_video_path(@project, @video)}']")
48
+ end
49
+ end
50
+
51
+ should "have a link to upload a new video" do
52
+ within("div.contextual") do
53
+ assert_have_selector("a", :href => new_project_video_path(@project))
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ context "Deleting a video by clicking the 'delete video' link" do
60
+ setup do
61
+ @video = Video.create!(:title => "Video 1", :description => "Description...", :url => "http://some-url-here.com/", :project_id => @project.id, :user_id => @user.id)
62
+ delete_via_redirect(project_video_path(@project, @video))
63
+ end
64
+
65
+ should "notify the user that the video was deleted" do
66
+ assert_have_selector(".notice")
67
+ end
68
+
69
+ should "removes the video from the project's list of videos" do
70
+ visit project_videos_path(@project)
71
+ assert_have_no_selector(".video##{@video.to_param}")
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,77 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../../test/test_helper')
2
+
3
+ # Ensure that we are using the temporary fixture path
4
+ Engines::Testing.set_fixture_path
5
+
6
+
7
+ require 'webrat'
8
+ require 'fakeweb'
9
+ require 'chili_videos'
10
+
11
+ FakeWeb.allow_net_connect = false
12
+
13
+ Webrat.configure do |config|
14
+ config.mode = :rails
15
+ end
16
+
17
+ module IntegrationTestHelper
18
+ def login_as(user="existing", password="existing")
19
+ visit "/login"
20
+ fill_in 'Login', :with => user
21
+ fill_in 'Password', :with => password
22
+ click_button 'login'
23
+ assert_response :success
24
+ assert User.current.logged?
25
+ end
26
+
27
+ def visit_project(project)
28
+ visit '/'
29
+ assert_response :success
30
+
31
+ click_link 'Projects'
32
+ assert_response :success
33
+
34
+ click_link project.name
35
+ assert_response :success
36
+ end
37
+
38
+ def assert_forbidden
39
+ assert_response :forbidden
40
+ assert_template 'common/403'
41
+ end
42
+
43
+ # Cleanup current_url to remove the host; sometimes it's present, sometimes it's not
44
+ def current_path
45
+ return nil if current_url.nil?
46
+ return current_url.gsub("http://www.example.com","")
47
+ end
48
+
49
+ end
50
+
51
+ module TransloaditServiceHelper
52
+ def workflow_results(identifier = :standard)
53
+ YAML.load(File.open("test/fixtures/#{identifier}_transloadit_response.json"))
54
+ end
55
+
56
+ def stub_assembly_url(assembly = nil, fixture_base_name = :single_video_processed)
57
+ response = "test/fixtures/#{fixture_base_name.to_s}_assembly.json"
58
+ url = assembly.blank? ? assembly_url : assembly.assembly_url
59
+ FakeWeb.register_uri(:get, url, :response => response)
60
+ end
61
+
62
+ def assembly_url
63
+ 'http://fake.transload.it/assembly_url'
64
+ end
65
+ end
66
+
67
+ class ActionController::IntegrationTest
68
+ include IntegrationTestHelper
69
+ end
70
+
71
+ class ActiveSupport::TestCase
72
+ include TransloaditServiceHelper
73
+ end
74
+
75
+ class ActionController::TestCase
76
+ include TransloaditServiceHelper
77
+ end
@@ -0,0 +1,57 @@
1
+ require 'test/test_helper'
2
+
3
+ class AssemblyProcessorTest < ActiveSupport::TestCase
4
+ context '.process' do
5
+ setup do
6
+ stub_assembly_url
7
+
8
+ @project = Project.generate!
9
+ @assembly = Assembly.generate!(:project_id => @project.id, :assembly_url => assembly_url)
10
+ end
11
+
12
+ should 'create a new Video' do
13
+ Video.destroy_all
14
+ AssemblyProcessor.process(@assembly)
15
+ assert_equal 1, Video.count
16
+ end
17
+
18
+ should 'associate the video with the same project as the assembly' do
19
+ AssemblyProcessor.process(@assembly)
20
+ assert_equal @project.id, Video.last.project_id
21
+ end
22
+
23
+ should 'associate the video with the same user as the assembly' do
24
+ AssemblyProcessor.process(@assembly)
25
+ assert_equal @assembly.user_id, Video.last.user_id
26
+ end
27
+
28
+ context 'when a single video was uploaded it' do
29
+ should "store the S3 URL of the video associated with the assembly in the 'video_url' attribute" do
30
+ expected_url = 'http://fakebucket.s3.amazonaws.com/f1/192f2b2cb1755ad4494707d82dc7a5/tester.flv'
31
+ AssemblyProcessor.process(@assembly)
32
+ assert_equal expected_url, Video.last.url
33
+ end
34
+
35
+ should "store the value of the 'title' custom field on the video" do
36
+ AssemblyProcessor.process(@assembly)
37
+ assert_equal 'Title here', Video.last.title
38
+ #assert_equal 'Description here', Video.last.description
39
+ end
40
+
41
+ should "store the value of the 'description' custom field on the video" do
42
+ AssemblyProcessor.process(@assembly)
43
+ assert_equal 'Description here', Video.last.description
44
+ end
45
+
46
+ should "store the value of the 'version_id' custom field on the video" do
47
+ AssemblyProcessor.process(@assembly)
48
+ assert_equal 2, Video.last.version_id
49
+ end
50
+
51
+ should "store the duration of the video" do
52
+ AssemblyProcessor.process(@assembly)
53
+ assert_equal 10, Video.last.duration
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,95 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class AssemblyTest < ActiveSupport::TestCase
4
+ def setup
5
+ @project = Project.generate!
6
+ stub_assembly_url
7
+ end
8
+
9
+ context "creation" do
10
+ should "set 'processed' attribute to false" do
11
+ assembly = Assembly.generate!(:processed => true)
12
+ assert_equal false, assembly.processed
13
+ end
14
+ end
15
+
16
+ context ".encodings" do
17
+ setup do
18
+ @assembly = Assembly.generate!(:project_id => @project.id, :assembly_url => assembly_url)
19
+ end
20
+
21
+ context "when one video was uploaded it should" do
22
+ setup do
23
+ service_response = 'test/fixtures/single_video_processed_assembly.json'
24
+ FakeWeb.register_uri(:get, assembly_url, :response => service_response)
25
+ end
26
+
27
+ should "return an enumerable with one item" do
28
+ assert 1, @assembly.encodings.count
29
+ end
30
+
31
+ should "include the URL of the transcoded file" do
32
+ expected_url = 'http://fakebucket.s3.amazonaws.com/f1/192f2b2cb1755ad4494707d82dc7a5/tester.flv'
33
+ encoding = @assembly.encodings.first
34
+ assert expected_url, encoding.url
35
+ end
36
+ end
37
+
38
+ context "when the workflow has not completed yet" do
39
+ setup do
40
+ service_response = 'test/fixtures/incomplete_assembly.json'
41
+ FakeWeb.register_uri(:get, assembly_url, :response => service_response)
42
+ end
43
+
44
+ should "raises an IncompleteAssembly exception" do
45
+ assert_raise(ChiliVideos::Error::IncompleteAssembly) {@assembly.encodings}
46
+ end
47
+ end
48
+ end
49
+
50
+ context ".custom_fields" do
51
+ setup do
52
+ @assembly = Assembly.generate!(:project_id => @project.id, :assembly_url => assembly_url)
53
+ service_response = 'test/fixtures/single_video_processed_assembly.json'
54
+ FakeWeb.register_uri(:get, assembly_url, :response => service_response)
55
+ end
56
+
57
+ should "return a Hash-like object with key-value pairs of custom fields stored on the assembly" do
58
+ assert @assembly.custom_fields.has_key?('project_id')
59
+ assert @assembly.custom_fields.has_key?('user_id')
60
+ end
61
+
62
+ should "return an object which resolves String or Symbol keys" do
63
+ assert @assembly.custom_fields.has_key?('project_id')
64
+ assert @assembly.custom_fields.has_key?(:user_id)
65
+ end
66
+ end
67
+
68
+ context "processing" do
69
+ context "when an assembly is successfully created" do
70
+ setup do
71
+ Video.destroy_all
72
+ end
73
+
74
+ # Observers not called when in non-prod mode
75
+ #should "process the assembly and create a new video" do
76
+ # @assembly = Assembly.generate!(:project_id => @project.id, :assembly_url => assembly_url)
77
+ # assert_equal 1, Video.count
78
+ #end
79
+
80
+ context "but the video service has not finished transcoding the content" do
81
+ setup do
82
+ FakeWeb.clean_registry
83
+ service_response = 'test/fixtures/incomplete_assembly.json'
84
+ FakeWeb.register_uri(:get, assembly_url, :response => service_response)
85
+ end
86
+
87
+ should "enque a delayed job to handle the processing on Redmine's side later" do
88
+ simple_mock = OpenStruct.new(:process => true)
89
+ AssemblyProcessor.expects(:delay).returns(simple_mock)
90
+ Assembly.generate!(:project_id => @project.id, :assembly_url => assembly_url)
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,49 @@
1
+ require File.dirname(__FILE__) + '/../../test_helper'
2
+
3
+ include ChiliVideos
4
+
5
+ class ConfigTest < ActiveSupport::TestCase
6
+ setup do
7
+ Setting["plugin_chili_videos"] = HashWithIndifferentAccess.new({:transloadit_api_key => 'api_key', :transloadit_workflow => 'workflow_name'})
8
+ end
9
+
10
+ context '.api_key' do
11
+ should "returns the value of the plugin's 'transloadit_api_key' setting" do
12
+ assert_equal 'api_key', ChiliVideos::Config.api_key
13
+ end
14
+ end
15
+
16
+ context '.workflow' do
17
+ should "returns the value of the plugin's 'transloadit_workflow' setting" do
18
+ assert_equal 'workflow_name', ChiliVideos::Config.workflow
19
+ end
20
+ end
21
+
22
+ context '.update' do
23
+ context 'when all required parameters are supplied' do
24
+ setup do
25
+ @new_values = {:api_key => 'updated-api', :workflow => 'workflow-update'}
26
+ end
27
+
28
+ should "the value of the plugin's 'api_key' setting is updated" do
29
+ assert_equal 'api_key', ChiliVideos::Config.api_key
30
+ ChiliVideos::Config.update(@new_values)
31
+ assert_equal @new_values[:api_key], ChiliVideos::Config.api_key
32
+ end
33
+
34
+ should "the value of the plugin's 'workflow-update'' setting is updated" do
35
+ assert_equal 'workflow_name', ChiliVideos::Config.workflow
36
+ ChiliVideos::Config.update(@new_values)
37
+ assert_equal @new_values[:workflow], ChiliVideos::Config.workflow
38
+ end
39
+ end
40
+
41
+ context 'when a required parameter is missing' do
42
+ should "an ArgumentError is raised" do
43
+ assert_raise(ArgumentError) {
44
+ ChiliVideos::Config.update(:api_key => 'api_key')
45
+ }
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,30 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class ChiliVideosTest < ActiveSupport::TestCase
4
+ setup do
5
+ Setting["plugin_chili_videos"] = HashWithIndifferentAccess.new({:transloadit_api_key => 'api_key', :transloadit_workflow => 'workflow'})
6
+ end
7
+
8
+ context '.configured?' do
9
+ context "when all required settings are stored" do
10
+ should "return true" do
11
+ assert ChiliVideos.configured?
12
+ end
13
+ end
14
+
15
+ context "when 'transloadit_api_key' is not set" do
16
+ should 'returns false' do
17
+ Setting["plugin_chili_videos"]['transloadit_api_key'] = ''
18
+ assert !ChiliVideos.configured?
19
+ end
20
+ end
21
+
22
+ context "when 'transloadit_workflow' is not set" do
23
+ should 'returns false' do
24
+ Setting["plugin_chili_videos"]['transloadit_workflow'] = ''
25
+ assert !ChiliVideos.configured?
26
+ end
27
+ end
28
+ end
29
+ end
30
+
@@ -0,0 +1,26 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class VideoTest < ActiveSupport::TestCase
4
+ context "#length" do
5
+ context "when video is less than 1-minute" do
6
+ should "convert it to 0:XX format" do
7
+ video = Video.create!(:title => "Video 1", :duration => 32, :project_id => 1, :user_id => 1)
8
+ assert_equal "0:32", video.length
9
+ end
10
+ end
11
+
12
+ context "when video is longer than 1-minute" do
13
+ should "convert it to X:XX format" do
14
+ video = Video.create!(:title => "Video 1", :duration => 202, :project_id => 1, :user_id => 1)
15
+ assert_equal "3:22", video.length
16
+ end
17
+ end
18
+
19
+ context "when video duration is nil" do
20
+ should "return '0:00'" do
21
+ video = Video.create!(:title => "Video 1", :duration => nil, :project_id => 1, :user_id => 1)
22
+ assert_equal "0:00", video.length
23
+ end
24
+ end
25
+ end
26
+ end