google_r 0.2.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.
@@ -0,0 +1,44 @@
1
+ require 'ostruct'
2
+
3
+ class GoogleR::Token
4
+ attr_accessor :issued_to, :audience, :scopes, :expires_at, :access_type, :token
5
+
6
+ def initialize(token)
7
+ self.token = token
8
+ self.scopes = []
9
+ end
10
+
11
+ def self.url
12
+ "https://www.googleapis.com"
13
+ end
14
+
15
+ def self.api_headers
16
+ {}
17
+ end
18
+
19
+ def path
20
+ "/oauth2/v2/tokeninfo"
21
+ end
22
+
23
+ def self.from_json(json, *attrs)
24
+ token = self.new(*attrs)
25
+ token.issued_to = json["issued_to"]
26
+ token.audience = json["audience"]
27
+ token.scopes = json["scope"].split(" ")
28
+ token.expires_at = Time.at(Time.now.to_i + json["expires_in"])
29
+ token.access_type = json["access_type"]
30
+ token
31
+ end
32
+
33
+ def expires_in
34
+ expires_at.to_i - Time.now.to_i
35
+ end
36
+
37
+ def to_google(yajl_opts = {})
38
+ Yajl::Encoder.encode({}, yajl_opts)
39
+ end
40
+
41
+ def new?
42
+ self.token.nil?
43
+ end
44
+ end
@@ -0,0 +1,3 @@
1
+ class GoogleR
2
+ VERSION = "0.2.0"
3
+ end
@@ -0,0 +1,98 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:gContact="http://schemas.google.com/contact/2008" xmlns:batch="http://schemas.google.com/gdata/batch" xmlns:gd="http://schemas.google.com/g/2005" gd:etag="W/&quot;CEAGSHw9cSt7I2A9WhVSGEU.&quot;">
3
+ <id>michal@futuresimple.com</id>
4
+ <updated>2012-03-16T07:25:29.269Z</updated>
5
+ <category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/contact/2008#contact"/>
6
+ <title>Michal Bugno's Contacts</title>
7
+ <link rel="alternate" type="text/html" href="http://www.google.com/"/>
8
+ <link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/michal%40futuresimple.com/full"/>
9
+ <link rel="http://schemas.google.com/g/2005#post" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/michal%40futuresimple.com/full"/>
10
+ <link rel="http://schemas.google.com/g/2005#batch" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/michal%40futuresimple.com/full/batch"/>
11
+ <link rel="self" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/michal%40futuresimple.com/full?max-results=3"/>
12
+ <link rel="next" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/michal%40futuresimple.com/full?start-index=4&amp;max-results=3"/>
13
+ <author>
14
+ <name>Michal Bugno</name>
15
+ <email>michal@futuresimple.com</email>
16
+ </author>
17
+ <generator version="1.0" uri="http://www.google.com/m8/feeds">Contacts</generator>
18
+ <openSearch:totalResults>34</openSearch:totalResults>
19
+ <openSearch:startIndex>1</openSearch:startIndex>
20
+ <openSearch:itemsPerPage>3</openSearch:itemsPerPage>
21
+ <entry gd:etag="&quot;Q3o6cDVSLit7I2A9WhVSGEkOQgI.&quot;">
22
+ <id>http://www.google.com/m8/feeds/contacts/michal%40futuresimple.com/base/2f30e7d8bf01953</id>
23
+ <updated>2012-03-15T20:49:22.418Z</updated>
24
+ <app:edited xmlns:app="http://www.w3.org/2007/app">2012-03-15T20:49:22.418Z</app:edited>
25
+ <category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/contact/2008#contact"/>
26
+ <title>Sir Bartek Maciej Niemtur III</title>
27
+ <content>moje notatki</content>
28
+ <link rel="http://schemas.google.com/contacts/2008/rel#photo" type="image/*" href="https://www.google.com/m8/feeds/photos/media/michal%40futuresimple.com/2f30e7d8bf01953"/>
29
+ <link rel="self" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/michal%40futuresimple.com/full/2f30e7d8bf01953"/>
30
+ <link rel="edit" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/michal%40futuresimple.com/full/2f30e7d8bf01953"/>
31
+ <gd:name>
32
+ <gd:fullName>Sir Bartek Maciej Niemtur III</gd:fullName>
33
+ <gd:namePrefix>Sir</gd:namePrefix>
34
+ <gd:givenName yomi="Namtir">Bartek</gd:givenName>
35
+ <gd:additionalName>Maciej</gd:additionalName>
36
+ <gd:familyName yomi="Bortik">Niemtur</gd:familyName>
37
+ <gd:nameSuffix>III</gd:nameSuffix>
38
+ </gd:name>
39
+ <gContact:nickname>barti</gContact:nickname>
40
+ <gd:organization rel="http://schemas.google.com/g/2005#other">
41
+ <gd:orgName>Applicake</gd:orgName>
42
+ <gd:orgTitle>Klepacz</gd:orgTitle>
43
+ </gd:organization>
44
+ <gd:email rel="http://schemas.google.com/g/2005#home" address="lol@lol.home.com" primary="true"/>
45
+ <gd:email rel="http://schemas.google.com/g/2005#work" address="bart@work.com"/>
46
+ <gd:email rel="http://schemas.google.com/g/2005#other" address="mike@mike.com"/>
47
+ <gd:email label="Niestandardowy2" address="bart@bart.com"/>
48
+ <gd:phoneNumber rel="http://schemas.google.com/g/2005#mobile">komorkowy</gd:phoneNumber>
49
+ <gd:phoneNumber rel="http://schemas.google.com/g/2005#work">sluzbowy</gd:phoneNumber>
50
+ <gd:phoneNumber rel="http://schemas.google.com/g/2005#home">domowy</gd:phoneNumber>
51
+ <gd:phoneNumber rel="http://schemas.google.com/g/2005#main">glowny</gd:phoneNumber>
52
+ <gd:structuredPostalAddress rel="http://schemas.google.com/g/2005#home">
53
+ <gd:formattedAddress>ulica
54
+ skrytka
55
+ okolica, miasto, wojewodztwo kod
56
+ kraj</gd:formattedAddress>
57
+ <gd:street>ulica</gd:street>
58
+ <gd:neighborhood>okolica</gd:neighborhood>
59
+ <gd:pobox>skrytka</gd:pobox>
60
+ <gd:postcode>kod</gd:postcode>
61
+ <gd:city>miasto</gd:city>
62
+ <gd:region>wojewodztwo</gd:region>
63
+ <gd:country>kraj</gd:country>
64
+ </gd:structuredPostalAddress>
65
+ <gd:structuredPostalAddress rel="http://schemas.google.com/g/2005#work">
66
+ <gd:formattedAddress>ulica2
67
+ skrytka2
68
+ okolica2, miasto2, woj2 kod2
69
+ kraj2</gd:formattedAddress>
70
+ <gd:street>ulica2</gd:street>
71
+ <gd:neighborhood>okolica2</gd:neighborhood>
72
+ <gd:pobox>skrytka2</gd:pobox>
73
+ <gd:postcode>kod2</gd:postcode>
74
+ <gd:city>miasto2</gd:city>
75
+ <gd:region>woj2</gd:region>
76
+ <gd:country>kraj2</gd:country>
77
+ </gd:structuredPostalAddress>
78
+ <gContact:userDefinedField key="wlasne1" value="wlasnawartosc"/>
79
+ <gContact:groupMembershipInfo deleted="false" href="http://www.google.com/m8/feeds/groups/michal%40futuresimple.com/base/6"/>
80
+ <gContact:groupMembershipInfo deleted="false" href="http://www.google.com/m8/feeds/groups/michal%40futuresimple.com/base/5747930b8e7844f6"/>
81
+ </entry>
82
+ <entry gd:etag="&quot;Qnc4fzVSLit7I2A9WhVTGUgJTwA.&quot;">
83
+ <id>http://www.google.com/m8/feeds/contacts/michal%40futuresimple.com/base/8c7c7c80d9dcaf7</id>
84
+ <updated>2012-03-05T13:24:03.937Z</updated>
85
+ <app:edited xmlns:app="http://www.w3.org/2007/app">2012-03-05T13:24:03.937Z</app:edited>
86
+ <category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/contact/2008#contact"/>
87
+ <title>Awangarda druga</title>
88
+ <link rel="http://schemas.google.com/contacts/2008/rel#photo" type="image/*" href="https://www.google.com/m8/feeds/photos/media/michal%40futuresimple.com/8c7c7c80d9dcaf7"/>
89
+ <link rel="self" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/michal%40futuresimple.com/full/8c7c7c80d9dcaf7"/>
90
+ <link rel="edit" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/michal%40futuresimple.com/full/8c7c7c80d9dcaf7"/>
91
+ <gd:name>
92
+ <gd:fullName>Awangarda druga</gd:fullName>
93
+ <gd:givenName>Awangarda</gd:givenName>
94
+ <gd:familyName>druga</gd:familyName>
95
+ </gd:name>
96
+ <gContact:groupMembershipInfo deleted="false" href="http://www.google.com/m8/feeds/groups/michal%40futuresimple.com/base/6"/>
97
+ </entry>
98
+ </feed>
@@ -0,0 +1,20 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:gContact="http://schemas.google.com/contact/2008" xmlns:batch="http://schemas.google.com/gdata/batch" xmlns:gd="http://schemas.google.com/g/2005" gd:etag="W/&quot;D0EFSX8_cCt7I2A9WhVSGEQ.&quot;">
3
+ <id>michal@futuresimple.com</id>
4
+ <updated>2012-03-16T11:00:18.148Z</updated>
5
+ <category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/contact/2008#contact"/>
6
+ <title>Michal Bugno's Contacts</title>
7
+ <link rel="alternate" type="text/html" href="http://www.google.com/"/>
8
+ <link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/michal%40futuresimple.com/full"/>
9
+ <link rel="http://schemas.google.com/g/2005#post" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/michal%40futuresimple.com/full"/>
10
+ <link rel="http://schemas.google.com/g/2005#batch" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/michal%40futuresimple.com/full/batch"/>
11
+ <link rel="self" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/michal%40futuresimple.com/full?max-results=0"/>
12
+ <author>
13
+ <name>Michal Bugno</name>
14
+ <email>michal@futuresimple.com</email>
15
+ </author>
16
+ <generator version="1.0" uri="http://www.google.com/m8/feeds">Contacts</generator>
17
+ <openSearch:totalResults>34</openSearch:totalResults>
18
+ <openSearch:startIndex>1</openSearch:startIndex>
19
+ <openSearch:itemsPerPage>0</openSearch:itemsPerPage>
20
+ </feed>
@@ -0,0 +1,75 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <entry xmlns="http://www.w3.org/2005/Atom" xmlns:gContact="http://schemas.google.com/contact/2008" xmlns:batch="http://schemas.google.com/gdata/batch" xmlns:gd="http://schemas.google.com/g/2005" gd:etag="&quot;Q3o6cDVSLit7I2A9WhVSGEkOQgI.&quot;">
3
+ <id>http://www.google.com/m8/feeds/contacts/michal%40futuresimple.com/base/2f30e7d8bf01953</id>
4
+ <updated>2012-03-15T20:49:22.418Z</updated>
5
+ <app:edited xmlns:app="http://www.w3.org/2007/app">2012-03-15T20:49:22.418Z</app:edited>
6
+ <category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/contact/2008#contact"/>
7
+ <title>Sir Mike Thomas Bugno XI</title>
8
+ <content>Notes about Mike</content>
9
+
10
+ <link rel="http://schemas.google.com/contacts/2008/rel#photo" type="image/*" href="https://www.google.com/m8/feeds/photos/media/michal%40futuresimple.com/2f30e7d8bf01953"/>
11
+ <link rel="self" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/michal%40futuresimple.com/full/2f30e7d8bf01953"/>
12
+ <link rel="edit" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/michal%40futuresimple.com/full/2f30e7d8bf01953"/>
13
+
14
+ <gd:name>
15
+ <gd:fullName>Sir Mike Thomas Bugno XI</gd:fullName>
16
+ <gd:namePrefix>Sir</gd:namePrefix>
17
+ <gd:givenName yomi="Maik">Mike</gd:givenName>
18
+ <gd:additionalName>Thomas</gd:additionalName>
19
+ <gd:familyName yomi="Boogno">Bugno</gd:familyName>
20
+ <gd:nameSuffix>XI</gd:nameSuffix>
21
+ </gd:name>
22
+
23
+ <gContact:nickname>Majki</gContact:nickname>
24
+
25
+ <gd:organization rel="http://schemas.google.com/g/2005#other">
26
+ <gd:orgName>FutureSimple</gd:orgName>
27
+ <gd:orgTitle>Coder</gd:orgTitle>
28
+ </gd:organization>
29
+
30
+ <gd:email rel="http://schemas.google.com/g/2005#home" address="home@example.com" primary="true"/>
31
+ <gd:email rel="http://schemas.google.com/g/2005#work" address="work@example.com"/>
32
+ <gd:email rel="http://schemas.google.com/g/2005#other" address="other@example.com"/>
33
+ <gd:email label="Non standard" address="nonstandard@example.com"/>
34
+
35
+ <gd:phoneNumber rel="http://schemas.google.com/g/2005#mobile">43-mobile</gd:phoneNumber>
36
+ <gd:phoneNumber rel="http://schemas.google.com/g/2005#work">023-office</gd:phoneNumber>
37
+ <gd:phoneNumber rel="http://schemas.google.com/g/2005#home">444-home</gd:phoneNumber>
38
+ <gd:phoneNumber rel="http://schemas.google.com/g/2005#main">888-main</gd:phoneNumber>
39
+
40
+ <gd:structuredPostalAddress rel="http://schemas.google.com/g/2005#home">
41
+ <gd:formattedAddress>ulica
42
+ skrytka
43
+ okolica, miasto, wojewodztwo kod
44
+ kraj</gd:formattedAddress>
45
+ <gd:street>ulica</gd:street>
46
+ <gd:neighborhood>okolica</gd:neighborhood>
47
+ <gd:pobox>skrytka</gd:pobox>
48
+ <gd:postcode>kod</gd:postcode>
49
+ <gd:city>miasto</gd:city>
50
+ <gd:region>wojewodztwo</gd:region>
51
+ <gd:country>kraj</gd:country>
52
+ </gd:structuredPostalAddress>
53
+
54
+ <gd:structuredPostalAddress rel="http://schemas.google.com/g/2005#work">
55
+ <gd:formattedAddress>ulica2
56
+ skrytka2
57
+ okolica2, miasto2, wojedwodztwo2 kod2
58
+ kraj2</gd:formattedAddress>
59
+ <gd:street>ulica2</gd:street>
60
+ <gd:neighborhood>okolica2</gd:neighborhood>
61
+ <gd:pobox>skrytka2</gd:pobox>
62
+ <gd:postcode>kod2</gd:postcode>
63
+ <gd:city>miasto2</gd:city>
64
+ <gd:region>wojewodztwo2</gd:region>
65
+ <gd:country>kraj2</gd:country>
66
+ </gd:structuredPostalAddress>
67
+
68
+ <gContact:userDefinedField key="own key" value="Own value"/>
69
+
70
+ <gContact:website href="glowna.com" rel="home-page"/>
71
+ <gContact:website href="sluzbowy.com" rel="work"/>
72
+
73
+ <gContact:groupMembershipInfo deleted="false" href="http://www.google.com/m8/feeds/groups/michal%40futuresimple.com/base/6"/>
74
+ <gContact:groupMembershipInfo deleted="false" href="http://www.google.com/m8/feeds/groups/michal%40futuresimple.com/base/5747930b8e7844f6"/>
75
+ </entry>
@@ -0,0 +1,14 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <entry xmlns="http://www.w3.org/2005/Atom" xmlns:gContact="http://schemas.google.com/contact/2008" xmlns:batch="http://schemas.google.com/gdata/batch" xmlns:gd="http://schemas.google.com/g/2005" gd:etag="&quot;Qnw-eTVSLit7I2A9WhVREUgNQQ0.&quot;">
3
+ <id>http://www.google.com/m8/feeds/groups/michal%40futuresimple.com/base/5e8cb5e00cc22016</id>
4
+ <updated>2012-03-19T11:48:13.251Z</updated>
5
+ <app:edited xmlns:app="http://www.w3.org/2007/app">2012-03-19T11:48:13.251Z</app:edited>
6
+ <category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/contact/2008#group"/>
7
+ <title>Grupa 52</title>
8
+ <content>Grupa 52</content>
9
+ <extendedProperty name="Grupa 55">
10
+ <info>To jest grupa</info>
11
+ </extendedProperty>
12
+ <link rel="self" type="application/atom+xml" href="https://www.google.com/m8/feeds/groups/michal%40futuresimple.com/full/5e8cb5e00cc22016"/>
13
+ <link rel="edit" type="application/atom+xml" href="https://www.google.com/m8/feeds/groups/michal%40futuresimple.com/full/5e8cb5e00cc22016"/>
14
+ </entry>
@@ -0,0 +1,90 @@
1
+ require 'spec_helper'
2
+
3
+ describe GoogleR do
4
+
5
+ let(:api) { GoogleR.new("token") }
6
+
7
+ it "should process contacts" do
8
+ google_contacts = File.read('spec/fixtures/contact_list.xml');
9
+ connection_get_answer = double(:body => google_contacts,
10
+ :status => 200,
11
+ :headers => {"Content-Type" => "xml"})
12
+ allow(api).to receive_message_chain(:connection, :get).and_return(connection_get_answer)
13
+
14
+ data = api.contacts
15
+ expect(data.size).to eq(2)
16
+
17
+ contact_1 = data.find { |e| e.full_name == "Awangarda druga" }
18
+ expect(contact_1).not_to be_nil
19
+
20
+ contact_2 = data.find { |e| e.full_name == "Sir Bartek Maciej Niemtur III" }
21
+ expect(contact_2).not_to be_nil
22
+ end
23
+
24
+ it "should process groups"
25
+
26
+ it "should process events"
27
+
28
+ it "should handle accounts which have 0 contacts" do
29
+ no_contacts = File.read('spec/fixtures/no_contacts.xml')
30
+ connection_get_answer = double(:body => no_contacts,
31
+ :status => 200,
32
+ :headers => {"Content-Type" => "xml"})
33
+ allow_any_instance_of(GoogleR).to receive_message_chain(:connection, :get).and_return(connection_get_answer)
34
+
35
+ expect(api.connection(GoogleR::Contact)).to receive(:get)
36
+ expect(api.contacts).to be_empty
37
+ end
38
+
39
+ it "should raise error if request fails" do
40
+ connection_get_answer = double(:body => "Failed :(",
41
+ :status => 400)
42
+ allow_any_instance_of(GoogleR).to receive_message_chain(:connection, :get).and_return(connection_get_answer)
43
+ ex = nil
44
+ begin
45
+ api.contacts
46
+ rescue GoogleR::Error => e
47
+ ex = e
48
+ end
49
+ expect(ex.class).to eq(GoogleR::Error)
50
+ expect(ex.message).to include("400")
51
+ expect(ex.message).to include("Failed :(")
52
+ end
53
+
54
+ describe "test_access" do
55
+ context "when test response is 200" do
56
+ before do
57
+ response = double(:status => 200)
58
+ expect(api).to receive(:make_request).and_return(response)
59
+ end
60
+
61
+ it "returns true" do
62
+ expect(api.test_access).to eq(true)
63
+ end
64
+ end
65
+
66
+ context "when test response is 401" do
67
+ before do
68
+ response = double(:status => 401)
69
+ expect(api).to receive(:make_request).and_return(response)
70
+ end
71
+
72
+ it "returns true" do
73
+ expect(api.test_access).to eq(false)
74
+ end
75
+ end
76
+
77
+ context "when test response is somethig else" do
78
+ before do
79
+ response = double(:status => 500, :body => "Server error")
80
+ expect(api).to receive(:make_request).and_return(response)
81
+ end
82
+
83
+ it "raises GoogleR::Error" do
84
+ expect {
85
+ api.test_access
86
+ }.to raise_error(GoogleR::Error)
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,428 @@
1
+ require 'spec_helper'
2
+
3
+ describe GoogleR::Contact do
4
+ before do
5
+ single_contact_path = "spec/fixtures/single_contact.xml"
6
+ doc = Nokogiri::XML.parse(File.read(single_contact_path))
7
+ doc.remove_namespaces!
8
+ @doc_root = doc.root
9
+ end
10
+
11
+ let(:contact) { GoogleR::Contact.from_xml(@doc_root) }
12
+ subject { contact }
13
+
14
+ context "should load id and etag from xml" do
15
+ describe '#google_id' do
16
+ subject { super().google_id }
17
+ it { is_expected.to eq("http://www.google.com/m8/feeds/contacts/michal%40futuresimple.com/base/2f30e7d8bf01953") }
18
+ end
19
+
20
+ describe '#etag' do
21
+ subject { super().etag }
22
+ it { is_expected.to eq("\"Q3o6cDVSLit7I2A9WhVSGEkOQgI.\"") }
23
+ end
24
+ end
25
+
26
+ context "should load emails from xml" do
27
+ let (:emails) { GoogleR::Contact.from_xml(@doc_root).emails }
28
+ subject { emails }
29
+
30
+ describe '#size' do
31
+ subject { super().size }
32
+ it { is_expected.to eq(4) }
33
+ end
34
+
35
+ context "home_email" do
36
+ subject { emails.find { |e| e.rel == "http://schemas.google.com/g/2005#home" } }
37
+
38
+ describe '#address' do
39
+ subject { super().address }
40
+ it { is_expected.to eq("home@example.com") }
41
+ end
42
+
43
+ describe '#label' do
44
+ subject { super().label }
45
+ it { is_expected.to be_nil }
46
+ end
47
+
48
+ describe '#primary' do
49
+ subject { super().primary }
50
+ it { is_expected.to be_truthy }
51
+ end
52
+ end
53
+
54
+ context "work_email" do
55
+ subject { emails.find { |e| e.rel == "http://schemas.google.com/g/2005#work" } }
56
+
57
+ describe '#address' do
58
+ subject { super().address }
59
+ it { is_expected.to eq("work@example.com") }
60
+ end
61
+
62
+ describe '#label' do
63
+ subject { super().label }
64
+ it { is_expected.to be_nil }
65
+ end
66
+
67
+ describe '#primary' do
68
+ subject { super().primary }
69
+ it { is_expected.to be_falsey }
70
+ end
71
+ end
72
+
73
+ context "other_email" do
74
+ subject { emails.find { |e| e.rel == "http://schemas.google.com/g/2005#other" } }
75
+
76
+ describe '#address' do
77
+ subject { super().address }
78
+ it { is_expected.to eq("other@example.com") }
79
+ end
80
+
81
+ describe '#label' do
82
+ subject { super().label }
83
+ it { is_expected.to be_nil }
84
+ end
85
+
86
+ describe '#primary' do
87
+ subject { super().primary }
88
+ it { is_expected.to be_falsey }
89
+ end
90
+ end
91
+
92
+ context "custom_email" do
93
+ subject { emails.find { |e| e.rel.nil? } }
94
+
95
+ describe '#address' do
96
+ subject { super().address }
97
+ it { is_expected.to eq("nonstandard@example.com") }
98
+ end
99
+
100
+ describe '#label' do
101
+ subject { super().label }
102
+ it { is_expected.to eq("Non standard") }
103
+ end
104
+
105
+ describe '#primary' do
106
+ subject { super().primary }
107
+ it { is_expected.to be_falsey }
108
+ end
109
+ end
110
+
111
+ end
112
+
113
+ context "should load phones from xml" do
114
+ let (:phones) { GoogleR::Contact.from_xml(@doc_root).phones }
115
+ subject { phones }
116
+
117
+ describe '#size' do
118
+ subject { super().size }
119
+ it { is_expected.to eq(4) }
120
+ end
121
+
122
+ context "home_phone" do
123
+ subject { phones.find { |e| e.rel == "http://schemas.google.com/g/2005#home" } }
124
+
125
+ describe '#text' do
126
+ subject { super().text }
127
+ it { is_expected.to eq("444-home") }
128
+ end
129
+ end
130
+
131
+ context "work_phone" do
132
+ subject { phones.find { |e| e.rel == "http://schemas.google.com/g/2005#work" } }
133
+
134
+ describe '#text' do
135
+ subject { super().text }
136
+ it { is_expected.to eq("023-office") }
137
+ end
138
+ end
139
+
140
+ context "mobile_phone" do
141
+ subject { phones.find { |e| e.rel == "http://schemas.google.com/g/2005#mobile" } }
142
+
143
+ describe '#text' do
144
+ subject { super().text }
145
+ it { is_expected.to eq("43-mobile") }
146
+ end
147
+ end
148
+
149
+ context "main_phone" do
150
+ subject { phones.find { |e| e.rel == "http://schemas.google.com/g/2005#main" } }
151
+
152
+ describe '#text' do
153
+ subject { super().text }
154
+ it { is_expected.to eq("888-main") }
155
+ end
156
+ end
157
+ end
158
+
159
+ context "should load name from xml" do
160
+ describe '#name_prefix' do
161
+ subject { super().name_prefix }
162
+ it { is_expected.to eq("Sir") }
163
+ end
164
+
165
+ describe '#given_name' do
166
+ subject { super().given_name }
167
+ it { is_expected.to eq("Mike") }
168
+ end
169
+
170
+ describe '#additional_name' do
171
+ subject { super().additional_name }
172
+ it { is_expected.to eq("Thomas") }
173
+ end
174
+
175
+ describe '#family_name' do
176
+ subject { super().family_name }
177
+ it { is_expected.to eq("Bugno") }
178
+ end
179
+
180
+ describe '#name_suffix' do
181
+ subject { super().name_suffix }
182
+ it { is_expected.to eq("XI") }
183
+ end
184
+
185
+ describe '#full_name' do
186
+ subject { super().full_name }
187
+ it { is_expected.to eq("Sir Mike Thomas Bugno XI") }
188
+ end
189
+ end
190
+
191
+ context "should load content from xml" do
192
+ describe '#content' do
193
+ subject { super().content }
194
+ it { is_expected.to eq("Notes about Mike") }
195
+ end
196
+ end
197
+
198
+ context "should load updated from xml" do
199
+ describe '#updated' do
200
+ subject { super().updated }
201
+ it { is_expected.to eq(Time.parse("2012-03-15T20:49:22.418Z")) }
202
+ end
203
+ end
204
+
205
+ context "should load organisations from xml" do
206
+ let (:organizations) { GoogleR::Contact.from_xml(@doc_root).organizations }
207
+ subject { organizations }
208
+
209
+ describe '#size' do
210
+ subject { super().size }
211
+ it { is_expected.to eq(1) }
212
+ end
213
+
214
+ context "single organization" do
215
+ let (:organization) { GoogleR::Contact.from_xml(@doc_root).organizations.first }
216
+ subject { organization }
217
+
218
+ describe '#rel' do
219
+ subject { super().rel }
220
+ it { is_expected.to eq("http://schemas.google.com/g/2005#other") }
221
+ end
222
+
223
+ describe '#name' do
224
+ subject { super().name }
225
+ it { is_expected.to eq("FutureSimple") }
226
+ end
227
+
228
+ describe '#title' do
229
+ subject { super().title }
230
+ it { is_expected.to eq("Coder") }
231
+ end
232
+ end
233
+ end
234
+
235
+ context "should load user nickname from xml" do
236
+ describe '#nickname' do
237
+ subject { super().nickname }
238
+ it { should = "Majki"}
239
+ end
240
+ end
241
+
242
+ context "should load addresses from xml" do
243
+ let (:addresses) { GoogleR::Contact.from_xml(@doc_root).addresses }
244
+ subject { addresses }
245
+
246
+ describe '#size' do
247
+ subject { super().size }
248
+ it { is_expected.to eq(2) }
249
+ end
250
+
251
+ context "home" do
252
+ subject { addresses.find { |e| e.rel == "http://schemas.google.com/g/2005#home" } }
253
+
254
+ describe '#street' do
255
+ subject { super().street }
256
+ it { is_expected.to eq("ulica") }
257
+ end
258
+
259
+ describe '#neighborhood' do
260
+ subject { super().neighborhood }
261
+ it { is_expected.to eq("okolica") }
262
+ end
263
+
264
+ describe '#pobox' do
265
+ subject { super().pobox }
266
+ it { is_expected.to eq("skrytka") }
267
+ end
268
+
269
+ describe '#postcode' do
270
+ subject { super().postcode }
271
+ it { is_expected.to eq("kod") }
272
+ end
273
+
274
+ describe '#city' do
275
+ subject { super().city }
276
+ it { is_expected.to eq("miasto") }
277
+ end
278
+
279
+ describe '#region' do
280
+ subject { super().region }
281
+ it { is_expected.to eq("wojewodztwo") }
282
+ end
283
+
284
+ describe '#country' do
285
+ subject { super().country }
286
+ it { is_expected.to eq("kraj") }
287
+ end
288
+ end
289
+
290
+ context "work" do
291
+ subject { addresses.find { |e| e.rel == "http://schemas.google.com/g/2005#work" } }
292
+
293
+ describe '#street' do
294
+ subject { super().street }
295
+ it { is_expected.to eq("ulica2") }
296
+ end
297
+
298
+ describe '#neighborhood' do
299
+ subject { super().neighborhood }
300
+ it { is_expected.to eq("okolica2") }
301
+ end
302
+
303
+ describe '#pobox' do
304
+ subject { super().pobox }
305
+ it { is_expected.to eq("skrytka2") }
306
+ end
307
+
308
+ describe '#postcode' do
309
+ subject { super().postcode }
310
+ it { is_expected.to eq("kod2") }
311
+ end
312
+
313
+ describe '#city' do
314
+ subject { super().city }
315
+ it { is_expected.to eq("miasto2") }
316
+ end
317
+
318
+ describe '#region' do
319
+ subject { super().region }
320
+ it { is_expected.to eq("wojewodztwo2") }
321
+ end
322
+
323
+ describe '#country' do
324
+ subject { super().country }
325
+ it { is_expected.to eq("kraj2") }
326
+ end
327
+ end
328
+
329
+ end
330
+
331
+ context "should load group membership from xml" do
332
+ let (:groups) { GoogleR::Contact.from_xml(@doc_root).groups }
333
+ subject { groups }
334
+
335
+ describe '#size' do
336
+ subject { super().size }
337
+ it { is_expected.to eq(2) }
338
+ end
339
+
340
+ context "first" do
341
+ google_id = "http://www.google.com/m8/feeds/groups/michal%40futuresimple.com/base/6"
342
+ subject { groups.find { |e| e.google_id == google_id } }
343
+ it { is_expected.not_to be_nil }
344
+ end
345
+
346
+ context "last" do
347
+ google_id = "http://www.google.com/m8/feeds/groups/michal%40futuresimple.com/base/5747930b8e7844f6"
348
+ subject { groups.find { |e| e.google_id == google_id } }
349
+ it { is_expected.not_to be_nil }
350
+ end
351
+ end
352
+
353
+ context "should treat contact without google_id as new?" do
354
+ subject { GoogleR::Contact.new }
355
+ it { is_expected.to be_new }
356
+ end
357
+
358
+ context "should treat contact with google_id as !new?" do
359
+ it { is_expected.not_to be_new }
360
+ end
361
+
362
+ context "should load user fields from xml" do
363
+ describe '#user_fields' do
364
+ subject { super().user_fields }
365
+ it { is_expected.to eq({"own key" => "Own value"}) }
366
+ end
367
+ end
368
+
369
+ it "should load websites from xml" do
370
+ expect(contact.websites.map { |e| e.href }.sort).to eq(["glowna.com", "sluzbowy.com"].sort)
371
+ expect(contact.websites.map { |e| e.rel }.sort).to eq(["work", "home-page"].sort)
372
+ end
373
+
374
+ it "should generate valid xml" do
375
+ xml = contact.to_google
376
+ c = Nokogiri::XML.parse(xml)
377
+ c = c.root
378
+
379
+ expect(c.name).to eq("entry")
380
+ expect(c.namespace.prefix).to eq("atom")
381
+
382
+ expect(c.search("id").size).to eq(1)
383
+
384
+ expect(c.search("./gd:name/gd:givenName").size).to eq(1)
385
+ expect(c.search("./gd:name/gd:givenName").inner_text).to eq("Mike")
386
+ expect(c.search("./gd:name/gd:additionalName").size).to eq(1)
387
+ expect(c.search("./gd:name/gd:additionalName").inner_text).to eq("Thomas")
388
+ expect(c.search("./gd:name/gd:familyName").size).to eq(1)
389
+ expect(c.search("./gd:name/gd:familyName").inner_text).to eq("Bugno")
390
+ expect(c.search("./gd:name/gd:namePrefix").size).to eq(1)
391
+ expect(c.search("./gd:name/gd:namePrefix").inner_text).to eq("Sir")
392
+ expect(c.search("./gd:name/gd:nameSuffix").size).to eq(1)
393
+ expect(c.search("./gd:name/gd:nameSuffix").inner_text).to eq("XI")
394
+
395
+ expect(c.search("./atom:content").inner_text).to eq("Notes about Mike")
396
+
397
+ expect(c.search("./gContact:nickname").inner_text).to eq("Majki")
398
+
399
+ expect(c.search("./gd:phoneNumber").map { |e| e.inner_text }.sort).to eq(["43-mobile", "023-office", "444-home", "888-main"].sort)
400
+
401
+ expect(c.search("./gd:email").map { |e| e[:address] }).to eq(["home@example.com", "work@example.com", "other@example.com", "nonstandard@example.com"])
402
+ expect(c.search("./gd:email").map { |e| e[:primary] }).to eq(["true", "false", "false", "false"])
403
+
404
+ expect(c.search("./gd:organization/gd:orgName").size).to eq(1)
405
+ expect(c.search("./gd:organization/gd:orgName").inner_text).to eq("FutureSimple")
406
+ expect(c.search("./gd:organization/gd:orgTitle").size).to eq(1)
407
+ expect(c.search("./gd:organization/gd:orgTitle").inner_text).to eq("Coder")
408
+
409
+ expect(c.search("./gContact:groupMembershipInfo").size).to eq(2)
410
+ expect(c.search("./gContact:groupMembershipInfo").map { |e| e[:deleted] }).to eq(["false", "false"])
411
+
412
+ expect(c.search("./gContact:userDefinedField").size).to eq(1)
413
+ expect(c.search("./gContact:userDefinedField")[0][:key]).to eq("own key")
414
+ expect(c.search("./gContact:userDefinedField")[0][:value]).to eq("Own value")
415
+
416
+ websites = c.search("./gContact:website")
417
+ expect(websites.map { |e| e[:href] }.sort).to eq(["glowna.com", "sluzbowy.com"].sort)
418
+ expect(websites.map { |e| e[:rel] }.sort).to eq(["work", "home-page"].sort)
419
+ end
420
+
421
+ context "google api expectations" do
422
+ it "should send application/xml+atom content type for contacts" do
423
+ headers = GoogleR::Contact.api_headers
424
+ expect(headers).to have_key("Content-Type")
425
+ expect(headers["Content-Type"]).to eq("application/atom+xml")
426
+ end
427
+ end
428
+ end