vj-sdk 0.2.1
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.
- data/.gitignore +4 -0
- data/LICENSE +20 -0
- data/README.markdown +0 -0
- data/README.rdoc +7 -0
- data/Rakefile +70 -0
- data/VERSION.yml +4 -0
- data/lib/core_ext/cgi.rb +12 -0
- data/lib/core_ext/hash.rb +52 -0
- data/lib/core_ext/object.rb +15 -0
- data/lib/core_ext/string.rb +11 -0
- data/lib/sdk_connection_harness.rb +101 -0
- data/lib/videojuicer/asset/audio.rb +13 -0
- data/lib/videojuicer/asset/base.rb +80 -0
- data/lib/videojuicer/asset/flash.rb +8 -0
- data/lib/videojuicer/asset/image.rb +10 -0
- data/lib/videojuicer/asset/text.rb +8 -0
- data/lib/videojuicer/asset/video.rb +22 -0
- data/lib/videojuicer/campaign.rb +19 -0
- data/lib/videojuicer/campaign_policy.rb +116 -0
- data/lib/videojuicer/criterion/base.rb +56 -0
- data/lib/videojuicer/criterion/date_range.rb +15 -0
- data/lib/videojuicer/criterion/geolocation.rb +18 -0
- data/lib/videojuicer/criterion/request.rb +15 -0
- data/lib/videojuicer/criterion/time.rb +15 -0
- data/lib/videojuicer/criterion/week_day.rb +20 -0
- data/lib/videojuicer/oauth/multipart_helper.rb +96 -0
- data/lib/videojuicer/oauth/proxy_factory.rb +18 -0
- data/lib/videojuicer/oauth/request_proxy.rb +280 -0
- data/lib/videojuicer/presentation.rb +38 -0
- data/lib/videojuicer/preset.rb +29 -0
- data/lib/videojuicer/promo/base.rb +72 -0
- data/lib/videojuicer/resource/base.rb +175 -0
- data/lib/videojuicer/resource/collection.rb +36 -0
- data/lib/videojuicer/resource/embeddable.rb +30 -0
- data/lib/videojuicer/resource/errors.rb +17 -0
- data/lib/videojuicer/resource/inferrable.rb +141 -0
- data/lib/videojuicer/resource/property_registry.rb +145 -0
- data/lib/videojuicer/resource/relationships/belongs_to.rb +39 -0
- data/lib/videojuicer/resource/types.rb +28 -0
- data/lib/videojuicer/session.rb +74 -0
- data/lib/videojuicer/shared/configurable.rb +103 -0
- data/lib/videojuicer/shared/exceptions.rb +32 -0
- data/lib/videojuicer/user.rb +43 -0
- data/lib/videojuicer.rb +110 -0
- data/spec/assets/audio_spec.rb +25 -0
- data/spec/assets/flash_spec.rb +24 -0
- data/spec/assets/image_spec.rb +25 -0
- data/spec/assets/text_spec.rb +24 -0
- data/spec/assets/video_spec.rb +25 -0
- data/spec/belongs_to_spec.rb +45 -0
- data/spec/campaign_policy_spec.rb +41 -0
- data/spec/campaign_spec.rb +25 -0
- data/spec/collection_spec.rb +31 -0
- data/spec/criterion/date_range_spec.rb +24 -0
- data/spec/criterion/geolocation_spec.rb +23 -0
- data/spec/criterion/request_spec.rb +23 -0
- data/spec/criterion/time_spec.rb +23 -0
- data/spec/criterion/week_day_spec.rb +23 -0
- data/spec/files/audio.mp3 +0 -0
- data/spec/files/empty_file +0 -0
- data/spec/files/flash.swf +0 -0
- data/spec/files/image.jpg +0 -0
- data/spec/files/text.txt +1 -0
- data/spec/files/video.mov +0 -0
- data/spec/helpers/be_equal_to.rb +26 -0
- data/spec/helpers/spec_fixtures.rb +227 -0
- data/spec/helpers/spec_helper.rb +53 -0
- data/spec/presentation_spec.rb +25 -0
- data/spec/preset_spec.rb +30 -0
- data/spec/promos/audio_spec.rb +23 -0
- data/spec/promos/image_spec.rb +24 -0
- data/spec/promos/text_spec.rb +23 -0
- data/spec/promos/video_spec.rb +23 -0
- data/spec/property_registry_spec.rb +130 -0
- data/spec/request_proxy_spec.rb +90 -0
- data/spec/session_spec.rb +98 -0
- data/spec/shared/asset_spec.rb +39 -0
- data/spec/shared/configurable_spec.rb +75 -0
- data/spec/shared/dependent_spec.rb +40 -0
- data/spec/shared/embeddable_spec.rb +34 -0
- data/spec/shared/model_spec.rb +74 -0
- data/spec/shared/resource_spec.rb +140 -0
- data/spec/spec.opts +3 -0
- data/spec/user_spec.rb +42 -0
- data/spec/videojuicer_spec.rb +122 -0
- data/tasks/vj-core.rb +72 -0
- data/vj-sdk.gemspec +168 -0
- metadata +209 -0
@@ -0,0 +1,98 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "helpers", "spec_helper")
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
describe Videojuicer::Session do
|
5
|
+
|
6
|
+
before(:all) do
|
7
|
+
configure_test_settings
|
8
|
+
@session = Videojuicer::Session.new(
|
9
|
+
:seed_name => fixtures.seed.name,
|
10
|
+
:consumer_key => fixtures["write-master"].consumer.consumer_key,
|
11
|
+
:consumer_secret => fixtures["write-master"].consumer.consumer_secret,
|
12
|
+
:token => nil,
|
13
|
+
:token_secret => nil
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "instantiation" do
|
18
|
+
before(:all) do
|
19
|
+
@klass = Videojuicer::Session
|
20
|
+
end
|
21
|
+
it_should_behave_like "a configurable"
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "authorisation" do
|
25
|
+
describe "(retrieving the request token)" do
|
26
|
+
before(:all) do
|
27
|
+
@token = @session.get_request_token
|
28
|
+
end
|
29
|
+
|
30
|
+
it "fetches a token key" do
|
31
|
+
@token["oauth_token"].should be_kind_of(String)
|
32
|
+
@token["oauth_token"].should_not be_empty
|
33
|
+
end
|
34
|
+
it "fetches a token secret" do
|
35
|
+
@token["oauth_token_secret"].should be_kind_of(String)
|
36
|
+
@token["oauth_token_secret"].should_not be_empty
|
37
|
+
end
|
38
|
+
it "fetches the permissions" do
|
39
|
+
@token["permissions"].should == "read-user"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "(authorizing the request token)" do
|
44
|
+
before(:all) do
|
45
|
+
@authorize_url = @session.authorize_url
|
46
|
+
@authorize_url_parsed = URI.parse(@authorize_url)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "returns the URL when asked for the #authorize_url" do
|
50
|
+
@authorize_url_parsed.port.should == @session.port
|
51
|
+
@authorize_url_parsed.host.should == @session.host
|
52
|
+
end
|
53
|
+
it "returns a valid URL that can be successfully requested" do
|
54
|
+
req = Net::HTTP::Get.new("#{@authorize_url_parsed.path}?#{@authorize_url_parsed.query}")
|
55
|
+
response = Net::HTTP.start(@authorize_url_parsed.host, @authorize_url_parsed.port) do |http|
|
56
|
+
http.request req
|
57
|
+
end
|
58
|
+
response.code.to_i.should == 200
|
59
|
+
end
|
60
|
+
it "validates that mangling this URL in any way also mangles the response to an error state" do
|
61
|
+
req = Net::HTTP::Get.new("#{@authorize_url_parsed.path}?#{@authorize_url_parsed.query.gsub(/oauth_token=[a-zA-Z0-9]+/,'')}")
|
62
|
+
response = Net::HTTP.start(@authorize_url_parsed.host, @authorize_url_parsed.port) do |http|
|
63
|
+
http.request req
|
64
|
+
end
|
65
|
+
response.code.to_i.should == 401
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "(retrieving the access token)" do
|
70
|
+
before(:all) do
|
71
|
+
@atok_fixture = fixtures["write-master"].access_token
|
72
|
+
@atok = @session.exchange_request_token(@atok_fixture)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "fetches a token key" do
|
76
|
+
@atok.oauth_token.should be_kind_of(String)
|
77
|
+
@atok.oauth_token.should_not be_empty
|
78
|
+
end
|
79
|
+
it "fetches a token secret" do
|
80
|
+
@atok.oauth_token_secret.should be_kind_of(String)
|
81
|
+
@atok.oauth_token_secret.should_not be_empty
|
82
|
+
end
|
83
|
+
it "fetches the token permissions" do
|
84
|
+
@atok.permissions.should == "write-master"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "concurrency" do
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "scope control" do
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
shared_examples_for "an asset" do
|
2
|
+
before(:all) do
|
3
|
+
@preset = (@preset_params.nil? ? nil : Videojuicer::Preset.create(@preset_params.merge(:name => /\w{10}/.gen)))
|
4
|
+
@user = Videojuicer::User.first
|
5
|
+
raise "asset spec suite assumes at least one common user exists" if @user.nil?
|
6
|
+
end
|
7
|
+
|
8
|
+
after(:all) do
|
9
|
+
@preset.destroy unless @preset.nil?
|
10
|
+
end
|
11
|
+
|
12
|
+
before(:each) do
|
13
|
+
@original = @klass.gen unless @preset.nil?
|
14
|
+
end
|
15
|
+
|
16
|
+
after(:each) do
|
17
|
+
@original.destroy unless @preset.nil?
|
18
|
+
@derived.destroy unless @derived.nil?
|
19
|
+
end
|
20
|
+
|
21
|
+
it "external derivation should succeed" do
|
22
|
+
unless @preset.nil?
|
23
|
+
@derived = @klass.gen
|
24
|
+
@derived.derived_internally.should == nil
|
25
|
+
@derived.set_derived(@original, @preset)
|
26
|
+
@derived.should be_valid
|
27
|
+
@derived.derived_internally.should == false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it "internal derivation should succeed" do
|
32
|
+
unless @preset.nil?
|
33
|
+
@derived = @original.derive(@preset)
|
34
|
+
@derived.should be_valid
|
35
|
+
@derived.id.should_not == @original.id
|
36
|
+
@derived.derived_internally.should == true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
shared_examples_for "a configurable" do
|
2
|
+
|
3
|
+
before(:all) do
|
4
|
+
Videojuicer.configure!(:foo=>"custom", :bar=>"not overridden")
|
5
|
+
end
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
Videojuicer.exit_all!
|
9
|
+
end
|
10
|
+
|
11
|
+
after(:each) do
|
12
|
+
Videojuicer.exit_all!
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "scope control" do
|
16
|
+
before(:all) do
|
17
|
+
@configurable_a = @klass.new
|
18
|
+
@configurable_a.configure! :foo=>"a"
|
19
|
+
|
20
|
+
@configurable_b = @klass.new
|
21
|
+
@configurable_b.configure! :foo=>"b"
|
22
|
+
|
23
|
+
@configurable_c = @klass.new
|
24
|
+
@configurable_c.configure!({})
|
25
|
+
end
|
26
|
+
|
27
|
+
it "moves the configurable's local scope to the global scope stack" do
|
28
|
+
Videojuicer.current_scope.should_not == @configurable_a.config
|
29
|
+
@configurable_a.scope do |config|
|
30
|
+
config.should == Videojuicer.current_scope
|
31
|
+
end
|
32
|
+
Videojuicer.current_scope.should_not == @configurable_a.config
|
33
|
+
end
|
34
|
+
|
35
|
+
it "supports nested block behaviour" do
|
36
|
+
@configurable_a.scope do |config_a|
|
37
|
+
config_a[:bar].should == "not overridden"
|
38
|
+
config_a[:foo].should == "a"
|
39
|
+
|
40
|
+
Videojuicer.scopes.length.should == 2
|
41
|
+
|
42
|
+
@configurable_b.scope do |config_b|
|
43
|
+
Videojuicer.scopes.length.should == 3
|
44
|
+
config_b[:foo].should == "b"
|
45
|
+
config_b[:bar].should == "not overridden"
|
46
|
+
end
|
47
|
+
|
48
|
+
Videojuicer.scopes.length.should == 2
|
49
|
+
#raise "ALL SCOPES: #{Videojuicer.scopes.inspect} \n\n\n CURRENT SCOPE: #{Videojuicer.current_scope.inspect} \n\n BLOCK CONFIG: #{config.inspect}"
|
50
|
+
|
51
|
+
config_a[:foo].should == "a"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it "gets the configuration defaults from those already set on the Videojuicer module" do
|
57
|
+
obj = @klass.new
|
58
|
+
obj.config[:foo].should == "custom"
|
59
|
+
end
|
60
|
+
|
61
|
+
it "can override defaults from the Videojuicer configuration hash" do
|
62
|
+
obj = @klass.new
|
63
|
+
obj.configure!(:bar=>"overridden")
|
64
|
+
obj.config[:bar].should == "overridden"
|
65
|
+
end
|
66
|
+
|
67
|
+
%w(host port consumer_key consumer_secret token token_secret api_version seed_name protocol).each do |attr|
|
68
|
+
it "provides a direct access method for the #{attr} given in the configuration" do
|
69
|
+
obj = @klass.new
|
70
|
+
obj.configure!((attr.to_sym)=>"#{attr} was set")
|
71
|
+
obj.send(attr).should == "#{attr} was set"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
shared_examples_for "a dependent non-resource object" do
|
2
|
+
|
3
|
+
=begin
|
4
|
+
Dependent objects are non-resource objects that are typically members of a collection that is an attribute of a resource object.
|
5
|
+
|
6
|
+
Rather than a classic has_many/belongs_to relationship between RESTful objects, these objects are expressed as properties on the parent object -
|
7
|
+
they are *dependent* and unable to exist on their own.
|
8
|
+
|
9
|
+
In the SDK, helper classes for dependent objects are provided to allow creation and validation, but they do not allow dependent objects to be
|
10
|
+
saved as first-order objects. Instead, a parent object must be given the dependent object to add to its collection attribute.
|
11
|
+
|
12
|
+
This model currently applies to Criteria and Promo objects.
|
13
|
+
|
14
|
+
Expects @klass to be a reference to the model class being tested
|
15
|
+
Expects @parent to be a valid object ready to have objects of type @klass added to it.
|
16
|
+
Expects @singular_name to be a string containing the expected resource name, e.g. Videojuicer::User => "user"
|
17
|
+
Expects @plural_name to be a string containing the expected pluralised name, e.g. Videojuicer::User => "users"
|
18
|
+
Expects @good_attributes to be a hash of attributes for objects of the tested type that will successfully create a valid object.
|
19
|
+
=end
|
20
|
+
|
21
|
+
it_should_behave_like "a model"
|
22
|
+
|
23
|
+
it "has no get class method" do
|
24
|
+
lambda {@klass.get(9)}.should raise_error(NoMethodError)
|
25
|
+
end
|
26
|
+
it "has no all class method" do
|
27
|
+
lambda {@klass.all}.should raise_error(NoMethodError)
|
28
|
+
end
|
29
|
+
it "has no first class method" do
|
30
|
+
lambda {@klass.first}.should raise_error(NoMethodError)
|
31
|
+
end
|
32
|
+
it "has no save instance method" do
|
33
|
+
lambda {@klass.new.save}.should raise_error(NoMethodError)
|
34
|
+
end
|
35
|
+
it "has no destroy instance method" do
|
36
|
+
lambda {@klass.new.destroy}.should raise_error(NoMethodError)
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
shared_examples_for "an embeddable" do
|
2
|
+
|
3
|
+
# Requires same variables to be set as the shared resource spec.
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
@record = @klass.gen
|
7
|
+
@record.save.should be_true
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "getting the oembed payload" do
|
11
|
+
before(:all) do
|
12
|
+
@oembed_payload = @record.oembed_payload(700, 700)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should be parsed from JSON" do
|
16
|
+
@oembed_payload.should be_kind_of(Hash)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should have the embed source" do
|
20
|
+
@oembed_payload["html"].should_not be_blank
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "getting the embed code" do
|
25
|
+
before(:all) do
|
26
|
+
@src = @record.embed_code(700, 700)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should be populated" do
|
30
|
+
@src.should_not be_blank
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
shared_examples_for "a model" do
|
2
|
+
|
3
|
+
=begin
|
4
|
+
|
5
|
+
vj-sdk model classes, whether for first-order resources or for dependent objects, offer a suite of common functionality
|
6
|
+
|
7
|
+
this test covers those methods.
|
8
|
+
|
9
|
+
=end
|
10
|
+
|
11
|
+
# Expects @klass to be a reference to the model class being tested
|
12
|
+
# Expects @singular_name to be a string containing the expected resource name, e.g. Videojuicer::User => "user"
|
13
|
+
# Expects @plural_name to be a string containing the expected pluralised name, e.g. Videojuicer::User => "users"
|
14
|
+
# Expects @good_attributes to be a hash of attributes for objects of the tested type that will successfully create a valid object.
|
15
|
+
|
16
|
+
describe "a new record" do
|
17
|
+
before(:each) do
|
18
|
+
@record = @klass.new
|
19
|
+
end
|
20
|
+
|
21
|
+
it "returns true to #new_record?" do
|
22
|
+
@record.new_record?.should be_true
|
23
|
+
end
|
24
|
+
|
25
|
+
it "raises an exception when trying to pull attributes remotely" do
|
26
|
+
lambda {@record.reload}.should raise_error(Videojuicer::Exceptions::NoResource)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "returns false to #valid?" do
|
30
|
+
@record.valid?.should be_false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "inferrable naming" do
|
35
|
+
before(:all) do
|
36
|
+
class ::Nester
|
37
|
+
include Videojuicer::Resource::Inferrable
|
38
|
+
|
39
|
+
class Nested
|
40
|
+
include Videojuicer::Resource::Inferrable
|
41
|
+
|
42
|
+
class Leaf
|
43
|
+
include Videojuicer::Resource::Inferrable
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
it "has a resource name that matches the singular class name" do
|
50
|
+
@klass.resource_name.should == @singular_name
|
51
|
+
end
|
52
|
+
it "has a parameter name inferred from the resource name" do
|
53
|
+
@klass.parameter_name.should == @singular_name
|
54
|
+
end
|
55
|
+
it "has a resource path that properly pluralises the resource name" do
|
56
|
+
@klass.resource_route.should =~ /\/#{@plural_name}/
|
57
|
+
end
|
58
|
+
|
59
|
+
it "ascertains the containing class" do
|
60
|
+
::Nester.containing_class.should be_nil
|
61
|
+
::Nester::Nested.containing_class.should == ::Nester
|
62
|
+
::Nester::Nested::Leaf.containing_class.should == ::Nester::Nested
|
63
|
+
end
|
64
|
+
|
65
|
+
it "builds a nested route" do
|
66
|
+
::Nester::Nested::Leaf.resource_route.should == "/nesters/:nester_id/nesteds/:nested_id/leafs"
|
67
|
+
end
|
68
|
+
|
69
|
+
it "compiles a route" do
|
70
|
+
::Nester.compile_route("/foo/bar/:foo/:bar/foo", :foo=>"OMG", :bar=>"ROFLMAO").should == "/foo/bar/OMG/ROFLMAO/foo"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
shared_examples_for "a RESTFUL resource model" do
|
2
|
+
|
3
|
+
# Expects @klass to be a reference to the model class being tested
|
4
|
+
# Expects @singular_name to be a string containing the expected resource name, e.g. Videojuicer::User => "user"
|
5
|
+
# Expects @plural_name to be a string containing the expected pluralised name, e.g. Videojuicer::User => "users"
|
6
|
+
# Expects @good_attributes to be a hash of attributes for objects of the tested type that will successfully create a valid object.
|
7
|
+
|
8
|
+
it_should_behave_like "a model"
|
9
|
+
|
10
|
+
before(:all) do
|
11
|
+
@fixed_attributes ||= []
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "a new record" do
|
15
|
+
before(:each) do
|
16
|
+
@record = @klass.new
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "being saved" do
|
20
|
+
describe "successfully" do
|
21
|
+
before(:all) do
|
22
|
+
@successful = @klass.gen
|
23
|
+
raise @successful.errors.inspect unless @successful.valid?
|
24
|
+
@successful.valid?.should be_true
|
25
|
+
@saved = @successful.save
|
26
|
+
end
|
27
|
+
|
28
|
+
it "returns true" do
|
29
|
+
@saved.should == true
|
30
|
+
end
|
31
|
+
it "does not set any errors on the object" do
|
32
|
+
@successful.errors.should be_empty
|
33
|
+
end
|
34
|
+
it "gets an ID" do
|
35
|
+
@successful.id.should be_kind_of(Integer)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
describe "unsuccessfully" do
|
39
|
+
before(:all) do
|
40
|
+
@bad_attributes = @klass.gen_attributes.inject({}) do |memo, (key,value)|
|
41
|
+
memo.merge({key=>(@fixed_attributes.include?(key)? value : "")})
|
42
|
+
end
|
43
|
+
@fail = @klass.new(@bad_attributes)
|
44
|
+
@saved = @fail.save
|
45
|
+
end
|
46
|
+
|
47
|
+
it "is not #valid?" do
|
48
|
+
@fail.valid?.should be_false
|
49
|
+
end
|
50
|
+
|
51
|
+
it "returns false" do
|
52
|
+
@saved.should be_false
|
53
|
+
end
|
54
|
+
it "sets errors on the object" do
|
55
|
+
@fail.errors.should be_kind_of(Hash)
|
56
|
+
@fail.errors.should_not be_empty
|
57
|
+
end
|
58
|
+
it "does not get an ID" do
|
59
|
+
@fail.id.should be_nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "finding a record by ID" do
|
66
|
+
before(:all) do
|
67
|
+
@record = @klass.gen
|
68
|
+
@record.save.should be_true
|
69
|
+
@found = @klass.get(@record.id)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "gets all the attributes" do
|
73
|
+
attrs = @found.attributes.dup
|
74
|
+
attrs.delete(:id)
|
75
|
+
attrs = attrs.reject {|k,v| !v}
|
76
|
+
attrs.should_not be_empty
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "listing records" do
|
81
|
+
before(:all) do
|
82
|
+
@list = @klass.all
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should return a collection object" do
|
86
|
+
@list.should be_kind_of(Videojuicer::Resource::Collection)
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "with pagination settings" do
|
90
|
+
before(:all) do
|
91
|
+
@paginated_list = @klass.all(:limit=>5)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should return a collection object" do
|
95
|
+
@paginated_list.should be_kind_of(Videojuicer::Resource::Collection)
|
96
|
+
end
|
97
|
+
it "returns the proper amount of objects" do
|
98
|
+
@paginated_list.limit.should == 5
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "an existing record" do
|
104
|
+
before(:all) do
|
105
|
+
@record = @klass.gen
|
106
|
+
@record.save.should be_true
|
107
|
+
end
|
108
|
+
|
109
|
+
it "returns false to #new_record?" do
|
110
|
+
@record.new_record?.should be_false
|
111
|
+
end
|
112
|
+
|
113
|
+
it "uses an instance-specific resource path" do
|
114
|
+
@record.resource_path.should =~ /\/#{@plural_name}\/#{@record.id}\.json$/
|
115
|
+
end
|
116
|
+
|
117
|
+
it "reloads from the remote API successfully" do
|
118
|
+
@record.reload.should be_true
|
119
|
+
end
|
120
|
+
|
121
|
+
it "saves successfully" do
|
122
|
+
saved = @record.save
|
123
|
+
@record.errors.should == {}
|
124
|
+
saved.should be_true
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "deleting a record" do
|
129
|
+
before(:each) do
|
130
|
+
@record = @klass.gen
|
131
|
+
@record.save.should be_true
|
132
|
+
end
|
133
|
+
|
134
|
+
it "destroys the record" do
|
135
|
+
@record.destroy
|
136
|
+
lambda {@record.reload}.should raise_error(Videojuicer::Exceptions::NoResource)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/user_spec.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "helpers", "spec_helper")
|
2
|
+
|
3
|
+
describe Videojuicer::User do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
@klass = Videojuicer::User
|
7
|
+
configure_test_settings
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "instantiation" do
|
11
|
+
it_should_behave_like "a configurable"
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "general interface:" do
|
15
|
+
before(:all) do
|
16
|
+
@singular_name = "user"
|
17
|
+
@plural_name = "users"
|
18
|
+
end
|
19
|
+
|
20
|
+
it_should_behave_like "a RESTFUL resource model"
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "authentication" do
|
24
|
+
before(:all) do
|
25
|
+
@attrs = Videojuicer::User.gen_attributes
|
26
|
+
@auth_user = Videojuicer::User.new(@attrs)
|
27
|
+
@auth_user.save.should be_true
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
it "returns User with good credentials" do
|
32
|
+
u = Videojuicer::User.authenticate(@attrs[:login], @attrs[:password])
|
33
|
+
u.should be_kind_of(Videojuicer::User)
|
34
|
+
u.login.should == @attrs[:login]
|
35
|
+
end
|
36
|
+
|
37
|
+
it "returns nil with bad credentials" do
|
38
|
+
Videojuicer::User.authenticate(@attrs[:login], "FOOOOBARRRRRR").should be_nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "helpers", "spec_helper")
|
2
|
+
|
3
|
+
describe "Videojuicer SDK" do
|
4
|
+
|
5
|
+
describe "initialization with an options hash" do
|
6
|
+
before(:all) do
|
7
|
+
Videojuicer.configure!(
|
8
|
+
:consumer_key => "consumer_key",
|
9
|
+
:consumer_secret => "consumer_secret",
|
10
|
+
:api_version => 100,
|
11
|
+
:host => "host",
|
12
|
+
:port => 100
|
13
|
+
)
|
14
|
+
end
|
15
|
+
after(:all) do
|
16
|
+
Videojuicer.unconfigure!
|
17
|
+
end
|
18
|
+
|
19
|
+
it "respects the :consumer_key option" do
|
20
|
+
Videojuicer.default_options[:consumer_key].should == "consumer_key"
|
21
|
+
end
|
22
|
+
it "respects the :consumer_secret option" do
|
23
|
+
Videojuicer.default_options[:consumer_secret].should == "consumer_secret"
|
24
|
+
end
|
25
|
+
it "respects the :api_version option" do
|
26
|
+
Videojuicer.default_options[:api_version].should == 100
|
27
|
+
end
|
28
|
+
it "respects the :host option" do
|
29
|
+
Videojuicer.default_options[:host].should == "host"
|
30
|
+
end
|
31
|
+
it "respects the :port option" do
|
32
|
+
Videojuicer.default_options[:port].should == 100
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "scope management" do
|
37
|
+
before(:all) do
|
38
|
+
@default = {
|
39
|
+
:consumer_key => "consumer_key",
|
40
|
+
:consumer_secret => "consumer_secret",
|
41
|
+
:api_version => 100,
|
42
|
+
:host => "host",
|
43
|
+
:port => 100
|
44
|
+
}
|
45
|
+
Videojuicer.configure!(@default)
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "with no scope" do
|
49
|
+
it "should respond false to in_scope?" do
|
50
|
+
Videojuicer.in_scope?.should be_false
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should give the given defaults as the current scope" do
|
54
|
+
Videojuicer.current_scope.should == Videojuicer::DEFAULTS.merge(@default)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "entering a scope" do
|
59
|
+
before(:all) do
|
60
|
+
@scope1 = {:api_version=>"in scope 1", :scope_1_included=>true}
|
61
|
+
Videojuicer.enter_scope(@scope1)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should respond true to in_scope?" do
|
65
|
+
Videojuicer.in_scope?
|
66
|
+
end
|
67
|
+
it "should give the current scope config in response to current_scope" do
|
68
|
+
Videojuicer.current_scope.should == Videojuicer::DEFAULTS.merge(@default).merge(@scope1)
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "and then entering another scope" do
|
72
|
+
before(:all) do
|
73
|
+
@scope2 = {:api_version=>"in scope 2", :scope_2_included=>true}
|
74
|
+
Videojuicer.enter_scope(@scope2)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should respond true to in_scope?" do
|
78
|
+
Videojuicer.in_scope?
|
79
|
+
end
|
80
|
+
it "should inherit from the current scope" do
|
81
|
+
Videojuicer.current_scope.should == Videojuicer::DEFAULTS.merge(@default).merge(@scope1).merge(@scope2)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "and then exiting a scope" do
|
86
|
+
before(:all) do
|
87
|
+
@current_scope = Videojuicer.current_scope
|
88
|
+
@length_at_current_scope = Videojuicer.scopes.length
|
89
|
+
Videojuicer.enter_scope(:entered_scope=>1)
|
90
|
+
Videojuicer.current_scope.should_not == @current_scope
|
91
|
+
Videojuicer.exit_scope
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should reduce the scope stack length" do
|
95
|
+
Videojuicer.scopes.length.should == @length_at_current_scope
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should restore the current_scope to the previous value" do
|
99
|
+
Videojuicer.current_scope.should == @current_scope
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
describe "initialization with defaults" do
|
108
|
+
before(:all) do
|
109
|
+
Videojuicer.unconfigure!
|
110
|
+
Videojuicer.default_options.should == Videojuicer::DEFAULTS
|
111
|
+
end
|
112
|
+
|
113
|
+
it "provides a default host" do
|
114
|
+
Videojuicer.default_options[:port].should_not be_nil
|
115
|
+
end
|
116
|
+
|
117
|
+
it "provides a default port" do
|
118
|
+
Videojuicer.default_options[:host].should_not be_nil
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|