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