google_apps 0.5 → 0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +38 -0
- data/LICENSE +7 -0
- data/README.md +461 -0
- data/google_apps.gemspec +20 -0
- data/lib/google_apps/atom/atom.rb +6 -9
- data/lib/google_apps/atom/export.rb +5 -6
- data/lib/google_apps/atom/feed.rb +17 -6
- data/lib/google_apps/document_handler.rb +6 -38
- data/lib/google_apps/transport.rb +110 -194
- data/spec/credentials.example.yaml +2 -0
- data/spec/fixture_xml/mes_attr.xml +8 -0
- data/spec/fixture_xml/test_doc.xml +5 -0
- data/spec/fixture_xml/user.xml +5 -0
- data/spec/fixture_xml/users_feed.xml +49 -0
- data/spec/google_apps/apps_request_spec.rb +81 -0
- data/spec/google_apps/atom/document_spec.rb +74 -0
- data/spec/google_apps/atom/export_spec.rb +70 -0
- data/spec/google_apps/atom/feed_spec.rb +93 -0
- data/spec/google_apps/atom/group_member_spec.rb +49 -0
- data/spec/google_apps/atom/group_owner_spec.rb +43 -0
- data/spec/google_apps/atom/group_spec.rb +155 -0
- data/spec/google_apps/atom/message_attributes_spec.rb +73 -0
- data/spec/google_apps/atom/nickname_spec.rb +66 -0
- data/spec/google_apps/atom/node_spec.rb +57 -0
- data/spec/google_apps/atom/public_key_spec.rb +32 -0
- data/spec/google_apps/atom/user_spec.rb +304 -0
- data/spec/google_apps/document_handler_spec.rb +48 -0
- data/spec/google_apps/transport_spec.rb +235 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/support/helpers.rb +66 -0
- metadata +104 -6
@@ -0,0 +1,8 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<atom:entry xmlns:atom="http://www.w3.org/2005/Atom" xmlns:apps="http://schemas.google.com/apps/2006">
|
3
|
+
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/apps/2006#mailItem"/>
|
4
|
+
<atom:content xmlns:atom="http://www.w3.org/2005/Atom" type="message/rfc822"/>
|
5
|
+
<apps:label labelName="test"/>
|
6
|
+
<apps:label labelName="label"/>
|
7
|
+
<apps:mailItemProperty value="Inbox"/>
|
8
|
+
</atom:entry>
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<atom:entry xmlns:atom="http://www.w3.org/2005/Atom" xmlns:apps="http://schemas.google.com/apps/2006" xmlns:gd="http://schemas.google.com/g/2005">
|
3
|
+
<title type="text">Users</title>
|
4
|
+
<apps:property name="memberId" value="lholcomb2@cnm.edu"/>
|
5
|
+
</atom:entry>
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<atom:entry xmlns:atom="http://www.w3.org/2005/Atom" xmlns:apps="http://schemas.google.com/apps/2006">
|
2
|
+
<atom:category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/apps/2006#user"/>
|
3
|
+
<apps:login userName="lholcomb2" suspended="false"/>
|
4
|
+
<apps:name familyName="Holcomb" givenName="Lawrence"/>
|
5
|
+
</atom:entry>
|
@@ -0,0 +1,49 @@
|
|
1
|
+
<?xml version='1.0' encoding='UTF-8'?>
|
2
|
+
<feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'
|
3
|
+
xmlns:apps='http://schemas.google.com/apps/2006' xmlns:gd='http://schemas.google.com/g/2005'>
|
4
|
+
<id>https://apps-apis.google.com/a/feeds/loopb.ac/user/2.0</id>
|
5
|
+
<updated>1970-01-01T00:00:00.000Z</updated>
|
6
|
+
<category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/apps/2006#user'/>
|
7
|
+
<title type='text'>Users</title>
|
8
|
+
<link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml'
|
9
|
+
href='https://apps-apis.google.com/a/feeds/loopb.ac/user/2.0'/>
|
10
|
+
<link rel='http://schemas.google.com/g/2005#post' type='application/atom+xml'
|
11
|
+
href='https://apps-apis.google.com/a/feeds/loopb.ac/user/2.0'/>
|
12
|
+
<link rel='self' type='application/atom+xml' href='https://apps-apis.google.com/a/feeds/loopb.ac/user/2.0'/>
|
13
|
+
<link rel='next' type='application/atom+xml' href='https://apps-apis.google.com/a/feeds/cnm.edu/user/2.0?startUsername=aadams37'/>
|
14
|
+
<openSearch:startIndex>1</openSearch:startIndex>
|
15
|
+
<entry>
|
16
|
+
<id>https://apps-apis.google.com/a/feeds/loopb.ac/user/2.0/misterunfriendly</id>
|
17
|
+
<updated>1970-01-01T00:00:00.000Z</updated>
|
18
|
+
<category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/apps/2006#user'/>
|
19
|
+
<title type='text'>misterunfriendly</title>
|
20
|
+
<link rel='self' type='application/atom+xml'
|
21
|
+
href='https://apps-apis.google.com/a/feeds/loopb.ac/user/2.0/misterunfriendly'/>
|
22
|
+
<link rel='edit' type='application/atom+xml'
|
23
|
+
href='https://apps-apis.google.com/a/feeds/loopb.ac/user/2.0/misterunfriendly'/>
|
24
|
+
<apps:login userName='misterunfriendly' suspended='false' ipWhitelisted='false' admin='false'
|
25
|
+
changePasswordAtNextLogin='true' agreedToTerms='true'/>
|
26
|
+
<apps:quota limit='25600'/>
|
27
|
+
<apps:name familyName='Unfriendly' givenName='Mister'/>
|
28
|
+
<gd:feedLink rel='http://schemas.google.com/apps/2006#user.nicknames'
|
29
|
+
href='https://apps-apis.google.com/a/feeds/loopb.ac/nickname/2.0?username=misterunfriendly'/>
|
30
|
+
<gd:feedLink rel='http://schemas.google.com/apps/2006#user.emailLists'
|
31
|
+
href='https://apps-apis.google.com/a/feeds/loopb.ac/emailList/2.0?recipient=misterunfriendly%40loopb.ac'/>
|
32
|
+
</entry>
|
33
|
+
<entry>
|
34
|
+
<id>https://apps-apis.google.com/a/feeds/loopb.ac/user/2.0/will</id>
|
35
|
+
<updated>1970-01-01T00:00:00.000Z</updated>
|
36
|
+
<category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/apps/2006#user'/>
|
37
|
+
<title type='text'>will</title>
|
38
|
+
<link rel='self' type='application/atom+xml' href='https://apps-apis.google.com/a/feeds/loopb.ac/user/2.0/will'/>
|
39
|
+
<link rel='edit' type='application/atom+xml' href='https://apps-apis.google.com/a/feeds/loopb.ac/user/2.0/will'/>
|
40
|
+
<apps:login userName='will' suspended='false' ipWhitelisted='false' admin='true' changePasswordAtNextLogin='false'
|
41
|
+
agreedToTerms='true'/>
|
42
|
+
<apps:quota limit='25600'/>
|
43
|
+
<apps:name familyName='Read' givenName='Will'/>
|
44
|
+
<gd:feedLink rel='http://schemas.google.com/apps/2006#user.nicknames'
|
45
|
+
href='https://apps-apis.google.com/a/feeds/loopb.ac/nickname/2.0?username=will'/>
|
46
|
+
<gd:feedLink rel='http://schemas.google.com/apps/2006#user.emailLists'
|
47
|
+
href='https://apps-apis.google.com/a/feeds/loopb.ac/emailList/2.0?recipient=will%40loopb.ac'/>
|
48
|
+
</entry>
|
49
|
+
</feed>
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe GoogleApps::AppsRequest do
|
4
|
+
let (:request) { GoogleApps::AppsRequest.new :get, 'http://www.google.com', [['test', 'bob']] }
|
5
|
+
|
6
|
+
describe "#send_request" do
|
7
|
+
it "Sends the request as configured" do
|
8
|
+
stub_request(:get, "http://www.google.com/").
|
9
|
+
with(:headers => {'Test' => 'bob'}).
|
10
|
+
to_return(:status => 200)
|
11
|
+
request.send_request.should be_a Net::HTTPResponse
|
12
|
+
end
|
13
|
+
|
14
|
+
context "when the token is expired" do
|
15
|
+
xit "gets a new token and re-issues the request" do
|
16
|
+
stub_request(:get, "http://www.google.com/").
|
17
|
+
to_return(:status => 401)
|
18
|
+
transporter.get_user
|
19
|
+
body = <<-TEXT.strip!
|
20
|
+
client_id=#{transporter.client_id}&
|
21
|
+
client_secret=#{transporter.client_secret}&
|
22
|
+
refresh_token=#{transporter.refresh_token}&
|
23
|
+
grant_type=refresh_token
|
24
|
+
TEXT
|
25
|
+
a_request(:post, "https://accounts.google.com/o/oauth2/token").
|
26
|
+
with(body: body).should have_been_made
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#add_body" do
|
32
|
+
it "Adds the specified content to the request body" do
|
33
|
+
request.add_body 'test'
|
34
|
+
|
35
|
+
request.instance_eval { @http_request.body }.should == 'test'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#initialize_http" do
|
40
|
+
before(:all) do
|
41
|
+
@get = build_request :get
|
42
|
+
@put = build_request :put
|
43
|
+
@post = build_request :post
|
44
|
+
@delete = build_request :delete
|
45
|
+
end
|
46
|
+
|
47
|
+
it "Creates a Net::HTTP::Get object when passed 'get'" do
|
48
|
+
@get.instance_eval { @http_request }.should be_a Net::HTTP::Get
|
49
|
+
end
|
50
|
+
|
51
|
+
it "Creates a Net::HTTP::Put object when passed 'put'" do
|
52
|
+
@put.instance_eval { @http_request }.should be_a Net::HTTP::Put
|
53
|
+
end
|
54
|
+
|
55
|
+
it "Creates a Net::HTTP::Post object when passed 'post'" do
|
56
|
+
@post.instance_eval { @http_request }.should be_a Net::HTTP::Post
|
57
|
+
end
|
58
|
+
|
59
|
+
it "Creates a Net::HTTP::Delete object when passed 'delete'" do
|
60
|
+
@delete.instance_eval { @http_request }.should be_a Net::HTTP::Delete
|
61
|
+
end
|
62
|
+
|
63
|
+
it "Sets the uri according to the given argument" do
|
64
|
+
request.instance_eval { @uri.host }.should == 'www.google.com'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "#build_constant" do
|
69
|
+
it "Takes the given verb and returns the namespaced constant for that type of HTTP class" do
|
70
|
+
request.send(:build_constant, :put).to_s.should == 'Net::HTTP::Put'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "#set_headers" do
|
75
|
+
it "Sets the headers on @http_request" do
|
76
|
+
request.send(:set_headers, [['content-type', 'application/x-www-form-urlencoded']])
|
77
|
+
|
78
|
+
request.instance_eval { @http_request['content-type'] }.should == 'application/x-www-form-urlencoded'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "GoogleApps::Atom::Document" do
|
4
|
+
let (:document) { GoogleApps::Atom::Document.new File.read('spec/fixture_xml/user.xml') }
|
5
|
+
let (:doc_string) { File.read('spec/fixture_xml/test_doc.xml') }
|
6
|
+
|
7
|
+
describe "#parse" do
|
8
|
+
it "parses the given XML document" do
|
9
|
+
document.parse(doc_string).should be_a LibXML::XML::Document
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#make_document" do
|
14
|
+
it "turns the input into an LibXML::XML::Document" do
|
15
|
+
document.make_document(doc_string).should be_a LibXML::XML::Document
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#new_empty_doc" do
|
20
|
+
it "Returns a new empty LibXML::XML::Document" do
|
21
|
+
new_doc = document.new_empty_doc
|
22
|
+
|
23
|
+
new_doc.should be_a LibXML::XML::Document
|
24
|
+
new_doc.to_s.strip.should == '<?xml version="1.0" encoding="UTF-8"?>'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#find_and_update" do
|
29
|
+
it "Finds the specified node and updates the specified attributes" do
|
30
|
+
document.find_and_update('//apps:login', userName: ['lholcomb2', 'new'], suspended: ['false', 'senior'])
|
31
|
+
|
32
|
+
document.instance_eval { @doc }.find('//apps:login').first.attributes['userName'].should == 'new'
|
33
|
+
document.instance_eval { @doc }.find('//apps:login').first.attributes['suspended'].should == 'senior'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#build_root" do
|
38
|
+
before(:all) do
|
39
|
+
@root = document.build_root :user
|
40
|
+
end
|
41
|
+
|
42
|
+
it "Builds an atom:entry XML Node with the appropriate namespaces" do
|
43
|
+
@root.to_s.should include 'xmlns:atom'
|
44
|
+
@root.to_s.should include 'xmlns:apps'
|
45
|
+
end
|
46
|
+
|
47
|
+
it "Builds an atom:entry XML Node containing a category element" do
|
48
|
+
@root.to_s.should include 'apps:category'
|
49
|
+
end
|
50
|
+
|
51
|
+
it "Builds an atom:entry XML Node containing a category element of the right kind" do
|
52
|
+
@root.to_s.should include '2006#user'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#determine_namespaces" do
|
57
|
+
it "Builds a hash of the appropriate namespaces" do
|
58
|
+
ns = document.determine_namespaces(:user)
|
59
|
+
|
60
|
+
ns[:atom].should == GoogleApps::Atom::NAMESPACES[:atom]
|
61
|
+
ns[:apps].should == GoogleApps::Atom::NAMESPACES[:apps]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "#delete_node" do
|
66
|
+
it "Deletes the specified node from the document"
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "#to_s" do
|
70
|
+
it "Outputs @doc as a string" do
|
71
|
+
document.to_s.should be_a String
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "GoogleApps::Atom::Export" do
|
4
|
+
let (:export) { GoogleApps::Atom::Export.new }
|
5
|
+
let (:start) { '2012-2-20 00:00' }
|
6
|
+
let (:finish) { '2012-2-22 00:00' }
|
7
|
+
let (:query) { 'from:webmaster' }
|
8
|
+
let (:content) { 'HEADER_ONLY' }
|
9
|
+
|
10
|
+
describe "#new" do
|
11
|
+
it "should initialize @doc to an XML::Document" do
|
12
|
+
export.instance_eval { @doc }.should be_a LibXML::XML::Document
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#to_s" do
|
17
|
+
it "should return @doc as a String" do
|
18
|
+
export.to_s.should be_a String
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#add_prop" do
|
23
|
+
it "should add a property with the given name and value to the document" do
|
24
|
+
export.send :add_prop, 'food', 'bacon'
|
25
|
+
|
26
|
+
export.to_s.should include 'name="food"'
|
27
|
+
export.to_s.should include 'value="bacon"'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#start_date" do
|
32
|
+
it "should add a beginDate property to the export document" do
|
33
|
+
export.start_date start
|
34
|
+
|
35
|
+
export.to_s.should include 'name="beginDate"'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#end_date" do
|
40
|
+
it "should add an endDate property to the export document" do
|
41
|
+
export.end_date finish
|
42
|
+
|
43
|
+
export.to_s.should include 'name="endDate"'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#include_deleted" do
|
48
|
+
it "should add an includeDeleted property to the document" do
|
49
|
+
export.include_deleted
|
50
|
+
|
51
|
+
export.to_s.should include 'name="includeDeleted"'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#query" do
|
56
|
+
it "should add a searchQuery property to the document" do
|
57
|
+
export.query query
|
58
|
+
|
59
|
+
export.to_s.should include 'name="searchQuery"'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "#content" do
|
64
|
+
it "should add a packageContent property to the document" do
|
65
|
+
export.content content
|
66
|
+
|
67
|
+
export.to_s.should include 'name="packageContent"'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "GoogleApps::Atom::Feed" do
|
4
|
+
let (:xml) { File.read('spec/fixture_xml/users_feed.xml') }
|
5
|
+
let (:next_page) { 'https://apps-apis.google.com/a/feeds/cnm.edu/user/2.0?startUsername=aadams37' }
|
6
|
+
let (:feed) { GoogleApps::Atom::Feed.new(xml) }
|
7
|
+
let (:content_array) { ['<apps:login userId="Mom"/>', '<apps:quota value="80"/>', '<id/>', '<atom:category/>'] }
|
8
|
+
|
9
|
+
describe "#new" do
|
10
|
+
it "Parses the given xml" do
|
11
|
+
feed.doc.should be_a LibXML::XML::Document
|
12
|
+
end
|
13
|
+
|
14
|
+
it "Populates @items with Atom objects of the proper type" do
|
15
|
+
feed.items.first.should be_a GoogleApps::Atom::User
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#next_page" do
|
20
|
+
it "Sets the url for the next page in the feed" do
|
21
|
+
feed.next_page.should == next_page
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#entries_from" do
|
26
|
+
it "Builds an array of Atom objects" do # We have a bad regex somewhere, User doesn't work as an argument
|
27
|
+
results = feed.entries_from document: feed.doc, type: 'user', entry_tag: 'entry'
|
28
|
+
|
29
|
+
results.first.should be_a GoogleApps::Atom::User
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#new_doc" do
|
34
|
+
it "Returns a new Atom Document with the desired elements" do
|
35
|
+
doc = feed.new_doc 'user', content_array, ['apps:']
|
36
|
+
|
37
|
+
doc.to_s.should include '<apps:login'
|
38
|
+
doc.to_s.should include '<apps:quota'
|
39
|
+
doc.to_s.should_not include '<gd:category'
|
40
|
+
end
|
41
|
+
|
42
|
+
it "Returns a new Atom Document with the desired elements when given multiple filters" do
|
43
|
+
doc = feed.new_doc 'user', content_array, ['apps:', 'atom:']
|
44
|
+
|
45
|
+
doc.to_s.should include '<apps:login'
|
46
|
+
doc.to_s.should include '<atom:category'
|
47
|
+
doc.to_s.should_not include '<id'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "#add_category" do
|
52
|
+
it "Adds an atom:category node to the front of the content_array" do
|
53
|
+
content = feed.add_category(content_array, 'user').join("\n")
|
54
|
+
|
55
|
+
content.should include '<atom:category'
|
56
|
+
content.should include '#user'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "#entry_wrap" do
|
61
|
+
it "Wraps the given content in an apps:entry element" do
|
62
|
+
entry = feed.entry_wrap(["bob"]).join("\n")
|
63
|
+
|
64
|
+
entry.should include "<atom:entry xmlns:atom"
|
65
|
+
entry.should include "bob"
|
66
|
+
entry.should include "</atom:entry>"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "#node_to_ary" do
|
71
|
+
it "Returns the content of a node as an array" do
|
72
|
+
content = feed.node_to_ary(entry_node)
|
73
|
+
|
74
|
+
content.should be_an Array
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "#grab_elements" do
|
79
|
+
it "Grabs all elements from the content array matching the filter" do
|
80
|
+
matches = feed.grab_elements(content_array, 'apps:')
|
81
|
+
|
82
|
+
matches.each do |match|
|
83
|
+
match.should include 'apps:'
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "#determine_type" do
|
89
|
+
it "Returns snake cased document type from feed id" do
|
90
|
+
feed.determine_type(xml).should == 'user'
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "GoogleApps::Atom::GroupMember" do
|
4
|
+
let (:member) { GoogleApps::Atom::GroupMember.new }
|
5
|
+
|
6
|
+
describe "#new" do
|
7
|
+
it "initializes document as an empty Atom XML Document" do
|
8
|
+
member.instance_eval { @doc }.should be_a LibXML::XML::Document
|
9
|
+
end
|
10
|
+
|
11
|
+
it "sets the header for @doc" do
|
12
|
+
member.instance_eval { @doc.root.to_s.strip }.should == basic_header
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#member=" do
|
17
|
+
it "sets the value for the member being added" do
|
18
|
+
member.member = 'Bob'
|
19
|
+
|
20
|
+
member.member.should == 'Bob'
|
21
|
+
end
|
22
|
+
|
23
|
+
it "changes the value for @member if @member is already set" do
|
24
|
+
member.member = 'Tom'
|
25
|
+
member.member = 'Bill'
|
26
|
+
|
27
|
+
member.member.should == 'Bill'
|
28
|
+
member.to_s.should include 'Bill'
|
29
|
+
member.to_s.should_not include 'Tom'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#change_member" do
|
34
|
+
it "changes the XML Node for the memberId" do
|
35
|
+
member.member = 'Tom'
|
36
|
+
member.member = 'Bill'
|
37
|
+
|
38
|
+
member.instance_eval { @doc.root.child.attributes['value'] }.should == 'Bill'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "#to_s" do
|
43
|
+
it "returns @document as a string" do
|
44
|
+
member.member = 'Tom'
|
45
|
+
|
46
|
+
member.to_s.should == member.instance_eval { @doc.to_s }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|