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 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