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 CHANGED
@@ -1 +1 @@
1
- 0.3.5
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| Object.module_eval(el.name).new(:source_xml => el, :parent_handle => @owner.handle)}
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
@@ -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
- url_string = "#{API_URL}/GetUploadURL/#{self.options[:site]}.#{location}?#{self.generate_authorization_token}&type=XMLControlFile"
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)
@@ -0,0 +1,6 @@
1
+ module RTunesU
2
+ class File < Entity
3
+ composed_of :name, :path, :size, :shared
4
+ composed_of :size, :readonly => true
5
+ end
6
+ end
@@ -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
- xml_builder.tag!("SectionPath", '')
14
- xml_builder.tag!("MergeByHandle", "false")
15
- xml_builder.tag!("Destructive", "false")
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
- composed_of :name, :kind, :disc_number, :album_name, :arist_name, :category_code, :explicit
4
- composed_of :duration_in_milliseconds, :readonly => true
5
- composed_of :downloadURL, :as => 'DownloadURL'
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, course_handle, connection = nil)
32
+ def self.find(handle, group_handle, connection = nil)
10
33
  connection ||= self.base_connection
11
34
 
12
- entity = self.new
13
- entity.instance_variable_set('@handle', handle)
14
- entity.source_xml = Course.find(course_handle, connection).source_xml.at("Handle[text()=#{entity.handle}]..")
15
- entity
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
@@ -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 = Hpricot.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
@@ -1,9 +1,5 @@
1
1
  module RTunesU
2
2
  module VERSION #:nodoc:
3
- MAJOR = 0
4
- MINOR = 3
5
- TINY = 5
6
-
7
- STRING = [MAJOR, MINOR, TINY].join('.')
3
+ STRING = File.read(File.join(File.dirname(__FILE__), '../../VERSION')).strip!.freeze
8
4
  end
9
5
  end
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/subentities'
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
- it_should_be_composed_of_readonly :aggregate_file_size
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
- it_should_be_composed_of_readonly :aggregate_file_size
16
+ it_should_be_composed_of :aggregate_file_size, :readonly => true
17
17
  it_should_have_many :permissions, :sections
18
18
  end
@@ -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
- it_should_be_composed_of_readonly :aggregate_file_size
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
- before(:each) do
21
- @document = Hpricot.XML(@section.to_xml)
22
- end
23
- it "should have SectionPath element" do
24
- @document.at('SectionPath').should_not == nil
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
- it "should have MergeByHandle element" do
28
- @document.at('MergeByHandle').should_not == nil
29
- @document.at('MergeByHandle').innerHTML.should == "false"
30
- end
31
-
32
- it "should have Destructive element" do
33
- @document.at('Destructive').should_not == nil
34
- @document.at('Destructive').innerHTML.should == "false"
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
@@ -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.2394598528?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",
24
- :body => mock_upload_url_for_handle(1))
25
- FakeWeb.register_uri(:post, mock_upload_url_for_handle(1), :body => response_for(Course, 'show', true))
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 have an handle" do
33
- lambda { Track.find(2449134252, 2394598528) }.should_not raise_error
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>&lt;File#2681543744:\"vidtest.mov\":protected&gt;</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>&lt;File#2681543744:\"vidtest2.mov\":protected&gt;</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 />
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 have attribute #{attr.to_s}" do
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
- it "should access #{attr.to_s} from XML" do
23
-
24
- end
25
- end
26
- end
27
-
28
- def it_should_be_composed_of_readonly(*elems)
29
- elems.each do |attr|
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 many #{association}" do
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.3.5
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-26 00:00:00 -04:00
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
- - setup.rb
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