google_r 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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