rtunesu 0.3.5 → 0.4.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.
- 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
|