google_apps 0.5 → 0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ username: you@example.com
2
+ password: myF4ncyP4assword
@@ -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