rtunesu 0.3.5 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/rtunesu/{subentities.rb → associations.rb} +2 -2
- data/lib/rtunesu/connection.rb +6 -5
- data/lib/rtunesu/entities/file.rb +6 -0
- data/lib/rtunesu/entities/section.rb +6 -4
- data/lib/rtunesu/entities/track.rb +31 -8
- data/lib/rtunesu/entity.rb +3 -1
- data/lib/rtunesu/version.rb +1 -5
- data/lib/rtunesu.rb +3 -2
- data/spec/association_spec.rb +50 -0
- data/spec/entities/course_spec.rb +1 -1
- data/spec/entities/division_spec.rb +1 -1
- data/spec/entities/group_spec.rb +1 -1
- data/spec/entities/section_spec.rb +35 -13
- data/spec/entities/track_spec.rb +69 -6
- data/spec/entity_spec.rb +5 -0
- data/spec/fixtures/responses/success/create_with_file_track.xml +1 -0
- data/spec/fixtures/responses/success/show_group.xml +52 -1
- data/spec/fixtures/sounds-of-the-cafe.mov +0 -0
- data/spec/spec_helper.rb +15 -14
- metadata +8 -4
- data/setup.rb +0 -1585
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
@@ -32,12 +32,12 @@ module RTunesU
|
|
32
32
|
end
|
33
33
|
|
34
34
|
class HasNEntityCollectionProxy < SubentityAssociationProxy
|
35
|
-
delegate :[], :at, :first, :last, :size, :to => :target
|
35
|
+
delegate :[], :at, :first, :last, :size, :clear, :to => :target
|
36
36
|
attr_reader :target, :edits
|
37
37
|
|
38
38
|
def from_xml(name)
|
39
39
|
if @source_xml
|
40
|
-
@target = @source_xml.collect {|el|
|
40
|
+
@target = @source_xml.collect {|el| "RTunesU::#{name}".constantize.new(:source_xml => el, :parent_handle => @owner.handle)}
|
41
41
|
else
|
42
42
|
@target = []
|
43
43
|
end
|
data/lib/rtunesu/connection.rb
CHANGED
@@ -71,7 +71,7 @@ module RTunesU
|
|
71
71
|
|
72
72
|
if value.respond_to?(:read)
|
73
73
|
mime_type = MIME::Types.type_for(value.path)[0] || MIME::Types["application/octet-stream"][0]
|
74
|
-
body << "Content-Disposition: form-data; name=\"#{esc_key}\"; filename=\"#{File.basename(value.path)}\"#{crlf}"
|
74
|
+
body << "Content-Disposition: form-data; name=\"#{esc_key}\"; filename=\"#{::File.basename(value.path)}\"#{crlf}"
|
75
75
|
body << "Content-Type: #{mime_type.simplified}#{crlf*2}"
|
76
76
|
body << value.read
|
77
77
|
value.rewind
|
@@ -107,8 +107,9 @@ module RTunesU
|
|
107
107
|
end
|
108
108
|
|
109
109
|
# Sends a request to iTunes U for a valid upload location for a file.
|
110
|
-
def upload_url_for_location(location) #:nodoc:
|
111
|
-
|
110
|
+
def upload_url_for_location(location, is_xml = true) #:nodoc:
|
111
|
+
type_string = (is_xml ? "&type=XMLControlFile" : nil)
|
112
|
+
url_string = "#{API_URL}/GetUploadURL/#{self.options[:site]}.#{location}?#{self.generate_authorization_token}#{type_string}"
|
112
113
|
url = URI.parse(url_string)
|
113
114
|
http = Net::HTTP.new(url.host, url.port)
|
114
115
|
http.use_ssl = true
|
@@ -158,8 +159,8 @@ module RTunesU
|
|
158
159
|
}
|
159
160
|
end
|
160
161
|
|
161
|
-
def upload_file(file, handle)
|
162
|
-
upload_url = upload_url_for_location(handle)
|
162
|
+
def upload_file(file, handle, is_xml = true)
|
163
|
+
upload_url = upload_url_for_location(handle, is_xml)
|
163
164
|
|
164
165
|
url = URI.parse(upload_url)
|
165
166
|
http = Net::HTTP.new(url.host, url.port)
|
@@ -8,11 +8,13 @@ module RTunesU
|
|
8
8
|
|
9
9
|
# Sections have additional required attributes for updating. These attributes *must* appear
|
10
10
|
# in a specific order.
|
11
|
-
# see http://deimos.apple.com/rsrc/doc/iTunesUAdministratorsGuide/iTunesUWebServices/chapter_17_section_12.html
|
11
|
+
# see http://deimos.apple.com/rsrc/doc/iTunesUAdministratorsGuide/iTunesUWebServices/chapter_17_section_12.html
|
12
12
|
def to_xml(xml_builder = Builder::XmlMarkup.new)
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
if saved?
|
14
|
+
xml_builder.tag!("SectionPath", '')
|
15
|
+
xml_builder.tag!("MergeByHandle", "false")
|
16
|
+
xml_builder.tag!("Destructive", "false")
|
17
|
+
end
|
16
18
|
super
|
17
19
|
end
|
18
20
|
end
|
@@ -1,18 +1,41 @@
|
|
1
1
|
module RTunesU
|
2
2
|
class Track < Entity
|
3
|
-
|
4
|
-
composed_of :
|
5
|
-
|
3
|
+
attr_accessor :file
|
4
|
+
composed_of :name, :kind, :disc_number, :track_number,
|
5
|
+
:album_name, :arist_name, :category_code, :explicit,
|
6
|
+
:genre_name, :comment
|
7
|
+
|
8
|
+
composed_of :duration_in_milliseconds, :as => 'DurationMilliseconds', :readonly => true
|
9
|
+
composed_of :download_url, :as => 'DownloadURL', :readonly => true
|
10
|
+
has_a :remote_file, :as => 'File', :readonly => true
|
11
|
+
|
12
|
+
|
13
|
+
def create(connection = nil)
|
14
|
+
connection ||= self.base_connection
|
15
|
+
if file
|
16
|
+
response = connection.upload_file(file, self.parent_handle, false)
|
17
|
+
@parent_handle, @handle = response.split('.')[-2..-1]
|
18
|
+
self.source_xml = Group.find(@parent_handle, connection).source_xml.at("Track/Handle[text()=#{@handle}]/..")
|
19
|
+
self
|
20
|
+
else
|
21
|
+
super
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def update(connection = nil)
|
26
|
+
raise "Cannot save existing Track with new file attached. Delete the old track and create a new one instead." if file
|
27
|
+
super
|
28
|
+
end
|
6
29
|
|
7
30
|
# Tracks can only be found from within their Course.
|
8
31
|
# There is currently (v1.1.3) no way to find a Track separete from its Course in iTunes U.
|
9
|
-
def self.find(handle,
|
32
|
+
def self.find(handle, group_handle, connection = nil)
|
10
33
|
connection ||= self.base_connection
|
11
34
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
35
|
+
track = self.new
|
36
|
+
track.instance_variable_set('@handle', handle)
|
37
|
+
track.source_xml = Group.find(group_handle, connection).source_xml.at("Track/Handle[text()=#{handle}]/..")
|
38
|
+
track
|
16
39
|
end
|
17
40
|
end
|
18
41
|
end
|
data/lib/rtunesu/entity.rb
CHANGED
@@ -105,12 +105,13 @@ module RTunesU
|
|
105
105
|
# will be written to a hash of edits that will be saved to iTunes U using method_missing
|
106
106
|
def initialize(attrs = {})
|
107
107
|
attrs.each {|attribute, value| self.send("#{attribute}=", value)}
|
108
|
-
self.source_xml
|
108
|
+
self.source_xml ||= Hpricot.XML('')
|
109
109
|
end
|
110
110
|
|
111
111
|
def handle
|
112
112
|
@handle ||= handle_from_source
|
113
113
|
end
|
114
|
+
alias :id :handle
|
114
115
|
|
115
116
|
def handle_from_source
|
116
117
|
return nil unless self.source_xml
|
@@ -153,6 +154,7 @@ module RTunesU
|
|
153
154
|
# Clear the edits and restores the loaded object to its original form
|
154
155
|
def reload
|
155
156
|
self.edits.clear
|
157
|
+
self
|
156
158
|
end
|
157
159
|
|
158
160
|
# Returns the parent of the entity
|
data/lib/rtunesu/version.rb
CHANGED
data/lib/rtunesu.rb
CHANGED
@@ -12,6 +12,7 @@ require 'rtunesu/entity'
|
|
12
12
|
require 'rtunesu/entities/course'
|
13
13
|
require 'rtunesu/entities/division'
|
14
14
|
require 'rtunesu/entities/external_feed'
|
15
|
+
require 'rtunesu/entities/file'
|
15
16
|
require 'rtunesu/entities/group'
|
16
17
|
require 'rtunesu/entities/permission'
|
17
18
|
require 'rtunesu/entities/section'
|
@@ -19,12 +20,12 @@ require 'rtunesu/entities/site'
|
|
19
20
|
require 'rtunesu/entities/track'
|
20
21
|
require 'rtunesu/entities/theme'
|
21
22
|
require 'rtunesu/log'
|
22
|
-
require 'rtunesu/
|
23
|
+
require 'rtunesu/associations'
|
23
24
|
|
24
25
|
module RTunesU
|
25
26
|
API_URL = 'https://deimos.apple.com/WebObjects/Core.woa/API'.freeze
|
26
27
|
API_VERSION = '1.1.3'.freeze
|
27
28
|
BROWSE_URL = 'https://deimos.apple.com/WebObjects/Core.woa/Browse'.freeze
|
28
29
|
SHOW_TREE_URL = 'https://deimos.apple.com/WebObjects/Core.woa/API/ShowTree'.freeze
|
29
|
-
SHOW_TREE_FILE = File.new(File.join(File.dirname(__FILE__), 'show_tree.xml'))
|
30
|
+
SHOW_TREE_FILE = ::File.new(::File.join(::File.dirname(__FILE__), 'show_tree.xml'))
|
30
31
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
include RTunesU
|
3
|
+
|
4
|
+
describe "associations" do
|
5
|
+
before(:each) do
|
6
|
+
mock_connect!
|
7
|
+
id = 2628591672
|
8
|
+
FakeWeb.register_uri(:get,
|
9
|
+
"https://deimos.apple.com/WebObjects/Core.woa/API/GetUploadURL/example.edu.#{id}?credentials=Administrator%40urn%3Amace%3Aitunesu.com%3Asites%3Aexample.edu&identity=%22Admin%22+%3Cadmin%40example.edu%3E+%28admin%29+%5B0%5D&time=1214619134&signature=121a6cf76c9c5ecda41450d87e3394b9d02c570a5f76b2bd16287f860f068302&type=XMLControlFile",
|
10
|
+
:body => mock_upload_url_for_handle(id))
|
11
|
+
FakeWeb.register_uri(:post, mock_upload_url_for_handle(id), :body => response_for(Group, 'show', true))
|
12
|
+
@group = Group.find(id)
|
13
|
+
end
|
14
|
+
|
15
|
+
after(:each) do
|
16
|
+
FakeWeb.clean_registry
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "has-a" do
|
20
|
+
it "should access the subentity" do
|
21
|
+
@group.external_feed.class.should == ExternalFeed
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should allow access to the subentity's attributes" do
|
25
|
+
@group.external_feed.polling_interval.should == 'Never'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "has-n" do
|
30
|
+
it "should access the subentity" do
|
31
|
+
@group.tracks.should_not be_nil
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should report the collections size" do
|
35
|
+
@group.tracks.size.should == 2
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should allow clearing the collections" do
|
39
|
+
@group.tracks.clear.should == []
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should allow subselections of the collections" do
|
43
|
+
@group.tracks[1].should be_kind_of(Track)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should allow access to the subentity's attributes" do
|
47
|
+
@group.tracks[0].handle.should_not == nil
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -15,6 +15,6 @@ describe Course do
|
|
15
15
|
it_should_behave_like "an Entity"
|
16
16
|
|
17
17
|
it_should_be_composed_of :name, :instructor, :description, :identifier, :theme_handle, :short_name, :allow_subscription
|
18
|
-
|
18
|
+
it_should_be_composed_of :aggregate_file_size, :readonly => true
|
19
19
|
it_should_have_many :permissions, :groups
|
20
20
|
end
|
@@ -13,6 +13,6 @@ describe Division do
|
|
13
13
|
it_should_behave_like "an Entity"
|
14
14
|
|
15
15
|
it_should_be_composed_of :name, :short_name, :identifier, :allow_subscription, :theme_handle, :description
|
16
|
-
|
16
|
+
it_should_be_composed_of :aggregate_file_size, :readonly => true
|
17
17
|
it_should_have_many :permissions, :sections
|
18
18
|
end
|
data/spec/entities/group_spec.rb
CHANGED
@@ -13,7 +13,7 @@ describe Group do
|
|
13
13
|
it_should_behave_like "an Entity"
|
14
14
|
|
15
15
|
it_should_be_composed_of :name, :group_type, :short_name, :allow_subscription, :explicit
|
16
|
-
|
16
|
+
it_should_be_composed_of :aggregate_file_size, :readonly => true
|
17
17
|
it_should_have_many :permissions, :tracks, :shared_objects
|
18
18
|
it_should_have_a :external_feed
|
19
19
|
end
|
@@ -17,21 +17,43 @@ describe Section do
|
|
17
17
|
it_should_have_many :courses
|
18
18
|
|
19
19
|
describe "converted to XML" do
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
describe "when new" do
|
21
|
+
before(:each) do
|
22
|
+
@document = Hpricot.XML(@section.to_xml)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should not have SectionPath element" do
|
26
|
+
@document.at('SectionPath').should == nil
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should not have MergeByHandle element" do
|
30
|
+
@document.at('MergeByHandle').should == nil
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should not have Destructive element" do
|
34
|
+
@document.at('Destructive').should == nil
|
35
|
+
end
|
25
36
|
end
|
26
37
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
38
|
+
describe "when saved" do
|
39
|
+
before(:each) do
|
40
|
+
@section.instance_variable_set("@handle", '1')
|
41
|
+
@document = Hpricot.XML(@section.to_xml)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should have SectionPath element" do
|
45
|
+
@document.at('SectionPath').should_not == nil
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should have MergeByHandle element" do
|
49
|
+
@document.at('MergeByHandle').should_not == nil
|
50
|
+
@document.at('MergeByHandle').innerHTML.should == "false"
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should have Destructive element" do
|
54
|
+
@document.at('Destructive').should_not == nil
|
55
|
+
@document.at('Destructive').innerHTML.should == "false"
|
56
|
+
end
|
35
57
|
end
|
36
58
|
end
|
37
59
|
end
|
data/spec/entities/track_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
2
|
require File.dirname(__FILE__) + '/../entity_spec.rb'
|
3
|
-
|
3
|
+
require 'tempfile'
|
4
4
|
include RTunesU
|
5
5
|
|
6
6
|
describe Track do
|
@@ -11,27 +11,90 @@ describe Track do
|
|
11
11
|
@attributes = {:name => 'Sample Lecture'}
|
12
12
|
end
|
13
13
|
|
14
|
+
it_should_be_composed_of :name, :kind, :disc_number, :track_number, :album_name, :arist_name, :category_code, :explicit, :genre_name, :comment
|
15
|
+
it_should_be_composed_of :duration_in_milliseconds, :download_url, :readonly => true
|
16
|
+
it_should_have_a :remote_file
|
17
|
+
|
14
18
|
# it_should_behave_like "a creatable Entity"
|
15
19
|
# it_should_behave_like "an updateable Entity"
|
16
20
|
# it_should_behave_like "a deleteable Entity"
|
17
21
|
it_should_behave_like "an Entity with attribute assignment"
|
18
22
|
|
23
|
+
describe "creating" do
|
24
|
+
before(:each) do
|
25
|
+
@group_handle = 2628591672
|
26
|
+
@track_handle = 2681543745
|
27
|
+
mock_connect!
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "without local file" do
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "with local file " do
|
35
|
+
before(:each) do
|
36
|
+
# Fake call to create upload url for Group
|
37
|
+
FakeWeb.register_uri(:get,
|
38
|
+
"https://deimos.apple.com/WebObjects/Core.woa/API/GetUploadURL/example.edu.#{@group_handle}?credentials=Administrator%40urn%3Amace%3Aitunesu.com%3Asites%3Aexample.edu&identity=%22Admin%22+%3Cadmin%40example.edu%3E+%28admin%29+%5B0%5D&time=1214619134&signature=121a6cf76c9c5ecda41450d87e3394b9d02c570a5f76b2bd16287f860f068302",
|
39
|
+
:body => mock_upload_url_for_handle(@group_handle)
|
40
|
+
)
|
41
|
+
# Fake call to upload file to Group, then to upload ShowTree to group again
|
42
|
+
FakeWeb.register_uri(:post,
|
43
|
+
mock_upload_url_for_handle(@group_handle),
|
44
|
+
[
|
45
|
+
{:body => response_for(Track, 'create_with_file', true)},
|
46
|
+
{:body => response_for(Group, 'show', true)}
|
47
|
+
]
|
48
|
+
)
|
49
|
+
|
50
|
+
# Fake call to create upload url for Group, again for ShowTree on the Group
|
51
|
+
FakeWeb.register_uri(:get,
|
52
|
+
"https://deimos.apple.com/WebObjects/Core.woa/API/GetUploadURL/example.edu.#{@group_handle}?credentials=Administrator%40urn%3Amace%3Aitunesu.com%3Asites%3Aexample.edu&identity=%22Admin%22+%3Cadmin%40example.edu%3E+%28admin%29+%5B0%5D&time=1214619134&signature=121a6cf76c9c5ecda41450d87e3394b9d02c570a5f76b2bd16287f860f068302&type=XMLControlFile",
|
53
|
+
:body => mock_upload_url_for_handle(@group_handle)
|
54
|
+
)
|
55
|
+
|
56
|
+
@track.parent_handle = @group_handle
|
57
|
+
@track.file = fixture_file('sounds-of-the-cafe.mov')
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should save to iTunes" do
|
61
|
+
lambda { @track.save}.should_not raise_error
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should have track meta data from iTunesU" do
|
65
|
+
@track.save
|
66
|
+
@track.name.should == "vidtest"
|
67
|
+
@track.duration_in_milliseconds.should == "1000"
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should raise error if attempting to update" do
|
71
|
+
@track.instance_variable_set("@handle", 1)
|
72
|
+
lambda { @track.save}.should raise_error
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
19
77
|
describe "finding" do
|
20
78
|
before(:each) do
|
79
|
+
@group_handle = 2628591672
|
80
|
+
@track_handle = 2681543745
|
21
81
|
mock_connect!
|
22
82
|
FakeWeb.register_uri(:get,
|
23
|
-
"https://deimos.apple.com/WebObjects/Core.woa/API/GetUploadURL/example.edu
|
24
|
-
:body => mock_upload_url_for_handle(
|
25
|
-
FakeWeb.register_uri(:post, mock_upload_url_for_handle(
|
83
|
+
"https://deimos.apple.com/WebObjects/Core.woa/API/GetUploadURL/example.edu.#{@group_handle}?credentials=Administrator%40urn%3Amace%3Aitunesu.com%3Asites%3Aexample.edu&identity=%22Admin%22+%3Cadmin%40example.edu%3E+%28admin%29+%5B0%5D&time=1214619134&signature=121a6cf76c9c5ecda41450d87e3394b9d02c570a5f76b2bd16287f860f068302&type=XMLControlFile",
|
84
|
+
:body => mock_upload_url_for_handle(@group_handle))
|
85
|
+
FakeWeb.register_uri(:post, mock_upload_url_for_handle(@group_handle), :body => response_for(Group, 'show', true))
|
26
86
|
end
|
27
87
|
|
28
88
|
after(:each) do
|
29
89
|
FakeWeb.clean_registry
|
30
90
|
end
|
31
91
|
|
32
|
-
it "should
|
33
|
-
lambda { Track.find(
|
92
|
+
it "should be found via its course" do
|
93
|
+
lambda { Track.find(@track_handle, @group_handle) }.should_not raise_error
|
34
94
|
end
|
35
95
|
|
96
|
+
it "should have a handle" do
|
97
|
+
Track.find(@track_handle, @group_handle).handle.should_not == nil
|
98
|
+
end
|
36
99
|
end
|
37
100
|
end
|
data/spec/entity_spec.rb
CHANGED
@@ -139,6 +139,11 @@ shared_examples_for "an Entity with attribute assignment" do
|
|
139
139
|
@entity.instance_variable_set("@handle", "1")
|
140
140
|
@entity.handle.should == "1"
|
141
141
|
end
|
142
|
+
|
143
|
+
it "should use id as alias for handle" do
|
144
|
+
@entity.instance_variable_set("@handle", "1")
|
145
|
+
@entity.handle.should == @entity.id
|
146
|
+
end
|
142
147
|
end
|
143
148
|
|
144
149
|
describe "when handle instance variable is not set" do
|
@@ -0,0 +1 @@
|
|
1
|
+
umich.edu.2685546150.2628591672.2681543745
|
@@ -50,7 +50,58 @@
|
|
50
50
|
<ShortName />
|
51
51
|
<Permission />
|
52
52
|
<Explicit />
|
53
|
-
<Track
|
53
|
+
<Track>
|
54
|
+
<Name>vidtest</Name>
|
55
|
+
<Handle>2681543745</Handle>
|
56
|
+
<Kind>feature-movie</Kind>
|
57
|
+
<TrackNumber>0</TrackNumber>
|
58
|
+
<DiscNumber>1</DiscNumber>
|
59
|
+
<DurationMilliseconds>1000</DurationMilliseconds>
|
60
|
+
<AlbumName></AlbumName>
|
61
|
+
<ArtistName></ArtistName>
|
62
|
+
<GenreName></GenreName>
|
63
|
+
<DownloadURL>https://deimos.apple.com/WebObjects/Core.woa/DownloadTrack/umich.edu.2685546150.02686881839.2681543745</DownloadURL>
|
64
|
+
<File>
|
65
|
+
<Name><File#2681543744:\"vidtest.mov\":protected></Name>
|
66
|
+
<Path>/8e/c4/2c/f0/8ec42cf06d1fc18ef17e9d3f3084515b50e784225ab413d6e5c77981362b0867-2681543744.mov</Path>
|
67
|
+
<Size>237982</Size>
|
68
|
+
<Hash>8ec42cf06d1fc18ef17e9d3f3084515b50e784225ab413d6e5c77981362b0867</Hash>
|
69
|
+
<Handle>2681543744</Handle>
|
70
|
+
<Shared>true</Shared>
|
71
|
+
</File>
|
72
|
+
<Comment></Comment>
|
73
|
+
<CoverImage>
|
74
|
+
<Handle>2681543745</Handle>
|
75
|
+
<Shared>false</Shared>
|
76
|
+
</CoverImage>
|
77
|
+
<Explicit></Explicit>
|
78
|
+
</Track>
|
79
|
+
<Track>
|
80
|
+
<Name>vidtest2</Name>
|
81
|
+
<Handle>2681543746</Handle>
|
82
|
+
<Kind>feature-movie</Kind>
|
83
|
+
<TrackNumber>1</TrackNumber>
|
84
|
+
<DiscNumber>1</DiscNumber>
|
85
|
+
<DurationMilliseconds>1000</DurationMilliseconds>
|
86
|
+
<AlbumName></AlbumName>
|
87
|
+
<ArtistName></ArtistName>
|
88
|
+
<GenreName></GenreName>
|
89
|
+
<DownloadURL>https://deimos.apple.com/WebObjects/Core.woa/DownloadTrack/umich.edu.2685546150.02686881839.2681543745</DownloadURL>
|
90
|
+
<File>
|
91
|
+
<Name><File#2681543744:\"vidtest2.mov\":protected></Name>
|
92
|
+
<Path>/8e/c4/2c/f0/8ec42cf06d1fc18ef17e9d3f3084515b50e784225ab413d6e5c77981362b0867-2681543745.mov</Path>
|
93
|
+
<Size>237982</Size>
|
94
|
+
<Hash>8ec42cf06d1fc18ef17e9d3f3084515b50e784225ab413d6e5c77981362b0867</Hash>
|
95
|
+
<Handle>2681543744</Handle>
|
96
|
+
<Shared>true</Shared>
|
97
|
+
</File>
|
98
|
+
<Comment></Comment>
|
99
|
+
<CoverImage>
|
100
|
+
<Handle>2681543746</Handle>
|
101
|
+
<Shared>false</Shared>
|
102
|
+
</CoverImage>
|
103
|
+
<Explicit></Explicit>
|
104
|
+
</Track>
|
54
105
|
<SharedObjects />
|
55
106
|
<AggregateFileSize />
|
56
107
|
<AllowSubscription />
|
Binary file
|
data/spec/spec_helper.rb
CHANGED
@@ -7,29 +7,30 @@ FakeWeb.allow_net_connect = false
|
|
7
7
|
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
8
8
|
require 'rtunesu'
|
9
9
|
|
10
|
+
def fixture_file(name)
|
11
|
+
File.new(File.dirname(__FILE__) + "/fixtures/#{name}")
|
12
|
+
end
|
13
|
+
|
10
14
|
def response_for(klass, action, success)
|
11
15
|
success_string = success ? "success" : "failure"
|
12
16
|
File.read(File.dirname(__FILE__) + "/fixtures/responses/#{success_string}/#{action}_#{klass.name.demodulize.downcase}.xml")
|
13
17
|
end
|
14
18
|
|
15
19
|
def it_should_be_composed_of(*elems)
|
20
|
+
options = elems.extract_options!
|
16
21
|
elems.each do |attr|
|
17
|
-
it "should
|
22
|
+
it "should read attribute #{attr.to_s}" do
|
18
23
|
@entity.should respond_to(attr)
|
19
|
-
@entity.should respond_to("#{attr}=")
|
20
24
|
end
|
21
25
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
it "should have readonly attribute #{attr.to_s}" do
|
31
|
-
@entity.should respond_to(attr)
|
32
|
-
@entity.should_not respond_to("#{attr}=")
|
26
|
+
if options[:readonly]
|
27
|
+
it "should not write attrbiute #{attr.to_s}" do
|
28
|
+
@entity.should_not respond_to("#{attr}=")
|
29
|
+
end
|
30
|
+
else
|
31
|
+
it "should write attrbiute #{attr.to_s}" do
|
32
|
+
@entity.should respond_to("#{attr}=")
|
33
|
+
end
|
33
34
|
end
|
34
35
|
end
|
35
36
|
end
|
@@ -45,7 +46,7 @@ end
|
|
45
46
|
|
46
47
|
def it_should_have_a(*associations)
|
47
48
|
associations.each do |association|
|
48
|
-
it "should have
|
49
|
+
it "should have a #{association}" do
|
49
50
|
@entity.should respond_to(association)
|
50
51
|
@entity.send(association).should be_kind_of(HasAEntityCollectionProxy)
|
51
52
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rtunesu
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Trek Glowacki
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-10-
|
12
|
+
date: 2009-10-27 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -58,11 +58,13 @@ files:
|
|
58
58
|
- Rakefile
|
59
59
|
- VERSION
|
60
60
|
- lib/rtunesu.rb
|
61
|
+
- lib/rtunesu/associations.rb
|
61
62
|
- lib/rtunesu/connection.rb
|
62
63
|
- lib/rtunesu/document.rb
|
63
64
|
- lib/rtunesu/entities/course.rb
|
64
65
|
- lib/rtunesu/entities/division.rb
|
65
66
|
- lib/rtunesu/entities/external_feed.rb
|
67
|
+
- lib/rtunesu/entities/file.rb
|
66
68
|
- lib/rtunesu/entities/group.rb
|
67
69
|
- lib/rtunesu/entities/permission.rb
|
68
70
|
- lib/rtunesu/entities/section.rb
|
@@ -72,7 +74,6 @@ files:
|
|
72
74
|
- lib/rtunesu/entities/track.rb
|
73
75
|
- lib/rtunesu/entity.rb
|
74
76
|
- lib/rtunesu/log.rb
|
75
|
-
- lib/rtunesu/subentities.rb
|
76
77
|
- lib/rtunesu/user.rb
|
77
78
|
- lib/rtunesu/version.rb
|
78
79
|
- lib/show_tree.xml
|
@@ -80,7 +81,7 @@ files:
|
|
80
81
|
- script/destroy
|
81
82
|
- script/generate
|
82
83
|
- script/txt2html
|
83
|
-
-
|
84
|
+
- spec/association_spec.rb
|
84
85
|
- spec/connection_spec.rb
|
85
86
|
- spec/document_spec.rb
|
86
87
|
- spec/entities/course_spec.rb
|
@@ -122,6 +123,7 @@ files:
|
|
122
123
|
- spec/fixtures/responses/success/create_division.xml
|
123
124
|
- spec/fixtures/responses/success/create_group.xml
|
124
125
|
- spec/fixtures/responses/success/create_section.xml
|
126
|
+
- spec/fixtures/responses/success/create_with_file_track.xml
|
125
127
|
- spec/fixtures/responses/success/delete_course.xml
|
126
128
|
- spec/fixtures/responses/success/delete_division.xml
|
127
129
|
- spec/fixtures/responses/success/delete_group.xml
|
@@ -138,6 +140,7 @@ files:
|
|
138
140
|
- spec/fixtures/responses/success/update_section.txt
|
139
141
|
- spec/fixtures/responses/success/update_section.xml
|
140
142
|
- spec/fixtures/responses/success/update_site.xml
|
143
|
+
- spec/fixtures/sounds-of-the-cafe.mov
|
141
144
|
- spec/spec.opts
|
142
145
|
- spec/spec_helper.rb
|
143
146
|
- spec/token_generation_spec.rb
|
@@ -173,6 +176,7 @@ signing_key:
|
|
173
176
|
specification_version: 3
|
174
177
|
summary: A library for using Apple's iTunes U Webservices API
|
175
178
|
test_files:
|
179
|
+
- spec/association_spec.rb
|
176
180
|
- spec/connection_spec.rb
|
177
181
|
- spec/document_spec.rb
|
178
182
|
- spec/entities/course_spec.rb
|