google_apps 0.5 → 0.9
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/.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
|