googlecontacts 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/lib/google_contacts/auth.rb +2 -2
- data/lib/google_contacts/group.rb +1 -1
- data/lib/google_contacts/proxies/array.rb +9 -9
- data/lib/google_contacts/proxies/emails.rb +17 -17
- data/lib/google_contacts/proxies/hash.rb +6 -6
- data/lib/google_contacts/proxies/tag.rb +7 -7
- data/lib/google_contacts/wrapper.rb +1 -1
- data/spec/base_spec.rb +20 -20
- data/spec/proxies/array_spec.rb +10 -10
- data/spec/proxies/emails_spec.rb +22 -22
- data/spec/proxies/hash_spec.rb +7 -7
- data/spec/proxies/tag_spec.rb +11 -11
- data/spec/wrapper_spec.rb +13 -13
- metadata +21 -4
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.7
|
data/lib/google_contacts/auth.rb
CHANGED
@@ -12,11 +12,11 @@ module GoogleContacts
|
|
12
12
|
attr_accessor :consumer_secret
|
13
13
|
attr_accessor :callback_url
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
def self.consumer
|
17
17
|
::OAuth::Consumer.new(consumer_key, consumer_secret, GOOGLE_OAUTH)
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
def request_token(options)
|
21
21
|
self.class.consumer.get_request_token({
|
22
22
|
:oauth_callback => options[:callback]
|
@@ -5,34 +5,34 @@ module GoogleContacts
|
|
5
5
|
@parent = parent
|
6
6
|
@tag = options[:tag]
|
7
7
|
@attr = options[:attr]
|
8
|
-
|
8
|
+
|
9
9
|
reinitialize
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
def reinitialize
|
13
13
|
@current = sanitize(@parent.xml.xpath("./#{@tag}").map do |entry|
|
14
14
|
entry[@attr]
|
15
15
|
end)
|
16
|
-
|
16
|
+
|
17
17
|
# create a deep copy
|
18
18
|
@new = @current.map { |item| item.dup }
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
def changed?
|
22
22
|
@current != @new
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
def synchronize
|
26
26
|
@parent.remove_xml("./#{@tag}")
|
27
27
|
@new.each do |value|
|
28
28
|
@parent.insert_xml(@tag, { @attr => value })
|
29
29
|
end
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
def replace(content)
|
33
33
|
@new = sanitize([content].flatten)
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
private
|
37
37
|
# Extract href from arguments if the operation changes
|
38
38
|
# the contents of the array.
|
@@ -45,11 +45,11 @@ module GoogleContacts
|
|
45
45
|
@new = sanitize(@new)
|
46
46
|
result
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
49
|
def sanitize(array)
|
50
50
|
array.compact.uniq.sort
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
def href_from_items(*items)
|
54
54
|
items.map do |item|
|
55
55
|
if item.is_a?(::Array)
|
@@ -5,27 +5,27 @@ module GoogleContacts
|
|
5
5
|
@parent = parent
|
6
6
|
reinitialize
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
def reinitialize
|
10
10
|
@current = ::Hash[*@parent.xml.xpath("./gd:email").map do |entry|
|
11
11
|
email = Email.new(self, entry.attributes)
|
12
12
|
[email.address, email]
|
13
13
|
end.flatten]
|
14
|
-
|
14
|
+
|
15
15
|
# create a deep copy
|
16
16
|
@new = ::Hash[*@current.map do |k,v|
|
17
17
|
[k.dup, v.dup]
|
18
18
|
end.flatten]
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
def changed?
|
22
22
|
@current != @new
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
def primary
|
26
26
|
@new.values.find { |email| email.primary? } || @new.values.first
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
def primary!(address)
|
30
30
|
@new.each do |key, email|
|
31
31
|
if key == address
|
@@ -35,16 +35,16 @@ module GoogleContacts
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
def <<(address)
|
40
40
|
raise "Duplicate address" if @new[address]
|
41
41
|
add(address)
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
def [](address)
|
45
45
|
@new[address] || add(address)
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
def synchronize
|
49
49
|
@parent.remove_xml("./gd:email")
|
50
50
|
@new.each_pair do |address, email|
|
@@ -55,7 +55,7 @@ module GoogleContacts
|
|
55
55
|
def inspect
|
56
56
|
@new.values.inspect
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
private
|
60
60
|
def add(address)
|
61
61
|
set_primary = @new.empty?
|
@@ -63,7 +63,7 @@ module GoogleContacts
|
|
63
63
|
@new[address].primary = true if set_primary
|
64
64
|
@new[address]
|
65
65
|
end
|
66
|
-
|
66
|
+
|
67
67
|
def method_missing(sym, *args, &blk)
|
68
68
|
if [:size, :delete].include?(sym)
|
69
69
|
@new.send(sym, *args, &blk)
|
@@ -71,14 +71,14 @@ module GoogleContacts
|
|
71
71
|
super
|
72
72
|
end
|
73
73
|
end
|
74
|
-
|
74
|
+
|
75
75
|
class Email < ::HashWithIndifferentAccess
|
76
76
|
DEFAULTS = {
|
77
77
|
:rel => 'http://schemas.google.com/g/2005#home'
|
78
78
|
}.freeze
|
79
|
-
|
79
|
+
|
80
80
|
alias_attribute :name, :displayName
|
81
|
-
|
81
|
+
|
82
82
|
def initialize(parent, attributes = {})
|
83
83
|
super(DEFAULTS)
|
84
84
|
@parent = parent
|
@@ -87,11 +87,11 @@ module GoogleContacts
|
|
87
87
|
send("#{key}=", value)
|
88
88
|
end
|
89
89
|
end
|
90
|
-
|
90
|
+
|
91
91
|
def primary!
|
92
92
|
@parent.primary! self[:address]
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
95
|
def rel=(arg)
|
96
96
|
delete(:label)
|
97
97
|
method_missing("rel=", arg)
|
@@ -101,7 +101,7 @@ module GoogleContacts
|
|
101
101
|
delete(:rel)
|
102
102
|
method_missing("label=", arg)
|
103
103
|
end
|
104
|
-
|
104
|
+
|
105
105
|
def []=(key, value)
|
106
106
|
if "#{key}" == 'address' && self[key]
|
107
107
|
raise "Cannot modify email address"
|
@@ -112,7 +112,7 @@ module GoogleContacts
|
|
112
112
|
def dup
|
113
113
|
self.class.new(@parent, self)
|
114
114
|
end
|
115
|
-
|
115
|
+
|
116
116
|
def method_missing(sym, *args, &blk)
|
117
117
|
if sym.to_s =~ /^(\w+)(=|\?)?$/
|
118
118
|
case $2
|
@@ -6,32 +6,32 @@ module GoogleContacts
|
|
6
6
|
@tag = options[:tag]
|
7
7
|
@key = options[:key]
|
8
8
|
@value = options[:value]
|
9
|
-
|
9
|
+
|
10
10
|
reinitialize
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
def reinitialize
|
14
14
|
@current = HashWithIndifferentAccess.new
|
15
15
|
@parent.xml.xpath("./#{@tag}").map do |entry|
|
16
16
|
@current[entry[@key]] = entry[@value]
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
# create a deep copy
|
20
20
|
@new = HashWithIndifferentAccess.new
|
21
21
|
@current.each { |k,v| @new[k.dup] = v.dup }
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
def changed?
|
25
25
|
@current != @new
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
def synchronize
|
29
29
|
@parent.remove_xml("./#{@tag}")
|
30
30
|
@new.each_pair do |key, value|
|
31
31
|
@parent.insert_xml(@tag, @key => key, @value => value)
|
32
32
|
end
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
private
|
36
36
|
def method_missing(sym, *args, &blk)
|
37
37
|
@new.send(sym, *args, &blk)
|
@@ -7,33 +7,33 @@ module GoogleContacts
|
|
7
7
|
|
8
8
|
reinitialize
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def reinitialize
|
12
12
|
@current = node.try(:content)
|
13
13
|
@new = @current ? @current.dup : nil
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
def changed?
|
17
17
|
@current != @new
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
def replace(content)
|
21
21
|
@new = content.to_s
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
def synchronize
|
25
25
|
(node || insert_node).content = @new
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
private
|
29
29
|
def node
|
30
30
|
@parent.xml.at_xpath("./#{@tag}")
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
def insert_node
|
34
34
|
@parent.insert_xml(@tag)
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
def method_missing(sym, *args, &blk)
|
38
38
|
if @new.respond_to?(sym)
|
39
39
|
@new.send(sym, *args, &blk)
|
data/spec/base_spec.rb
CHANGED
@@ -10,39 +10,39 @@ describe GoogleContacts::Base do
|
|
10
10
|
GoogleContacts::Base.new(wrapper, 'some xml')
|
11
11
|
}.should raise_error(/cannot create instance/i)
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
describe "with an XML document" do
|
15
15
|
before(:each) do
|
16
16
|
@t = GoogleContacts::BaseTester.new(wrapper)
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
it "should default namespace to document default" do
|
20
20
|
node = @t.insert_xml 'tag'
|
21
21
|
node.namespace.href.should == 'http://www.w3.org/2005/Atom'
|
22
22
|
@t.xml.xpath('atom:tag').should have(1).node
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
it "should set namespace when specified in tag" do
|
26
26
|
node = @t.insert_xml 'gd:extendedProperty'
|
27
27
|
node.namespace.href.should == 'http://schemas.google.com/g/2005'
|
28
28
|
@t.xml.xpath('gd:extendedProperty').should have(1).node
|
29
|
-
|
29
|
+
|
30
30
|
node = @t.insert_xml 'gContact:birthday'
|
31
31
|
node.namespace.href.should == 'http://schemas.google.com/contact/2008'
|
32
32
|
@t.xml.xpath('gContact:birthday').should have(1).node
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
it "should raise on unknown namespace" do
|
36
36
|
lambda {
|
37
37
|
@t.insert_xml 'unknown:foo'
|
38
38
|
}.should raise_error(/unknown namespace/i)
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
it "should also set attributes if given" do
|
42
42
|
node = @t.insert_xml 'tag', :foo => 'bar'
|
43
43
|
node['foo'].should == 'bar'
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
it "should allow removing xml" do
|
47
47
|
@t.insert_xml 'gd:extendedProperty'
|
48
48
|
@t.xml.xpath('./gd:extendedProperty').should have(1).node
|
@@ -51,72 +51,72 @@ describe GoogleContacts::Base do
|
|
51
51
|
@t.xml.xpath('./gd:extendedProperty').should have(:no).nodes
|
52
52
|
end
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
describe "basic crud" do
|
56
56
|
before(:each) do
|
57
57
|
@wrapper = wrapper
|
58
58
|
@entry = GoogleContacts::BaseTester.new(@wrapper)
|
59
59
|
end
|
60
|
-
|
60
|
+
|
61
61
|
# It is not sane to try and save a default entry
|
62
62
|
it "should not save when an entry is new but has no changed fields" do
|
63
63
|
@entry.stubs(:new? => true, :changed? => false)
|
64
64
|
@wrapper.expects(:append_operation).never
|
65
65
|
@entry.save
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
it "should save when an entry is new and has changed fields" do
|
69
69
|
@entry.stubs(:new? => true, :changed? => true)
|
70
70
|
@wrapper.expects(:append_operation).with(@entry, :insert)
|
71
71
|
@entry.save
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
it "should save when an entry has changed fields" do
|
75
75
|
@entry.stubs(:new? => false, :changed? => true)
|
76
76
|
@wrapper.expects(:append_operation).with(@entry, :update)
|
77
77
|
@entry.save
|
78
78
|
end
|
79
|
-
|
79
|
+
|
80
80
|
it "should not delete when an entry is new" do
|
81
81
|
@entry.stubs(:new? => true)
|
82
82
|
@wrapper.expects(:append_operation).never
|
83
83
|
@entry.delete
|
84
84
|
end
|
85
|
-
|
85
|
+
|
86
86
|
it "should delete when an entry is not new" do
|
87
87
|
@entry.stubs(:new? => false)
|
88
88
|
@wrapper.expects(:append_operation).with(@entry, :delete)
|
89
89
|
@entry.delete
|
90
90
|
end
|
91
91
|
end
|
92
|
-
|
92
|
+
|
93
93
|
describe "prepare for batch operation" do
|
94
94
|
before(:all) do
|
95
95
|
@t = GoogleContacts::BaseTester.new(wrapper, parsed_asset('contacts_full').at('feed > entry'))
|
96
96
|
@batch = @t.entry_for_batch(:update)
|
97
97
|
end
|
98
|
-
|
98
|
+
|
99
99
|
it "should not share the same document" do
|
100
100
|
@batch.document.should_not == @t.xml.document
|
101
101
|
end
|
102
|
-
|
102
|
+
|
103
103
|
it "should create a duplicate node without link tags" do
|
104
104
|
@batch.xpath('./atom:link').should be_empty
|
105
105
|
end
|
106
|
-
|
106
|
+
|
107
107
|
it "should not touch the category tag" do
|
108
108
|
@batch.xpath('./atom:category').should_not be_nil
|
109
109
|
end
|
110
|
-
|
110
|
+
|
111
111
|
it "should remove the updated tag (not useful when updating)" do
|
112
112
|
@batch.xpath('./atom:updated').should be_empty
|
113
113
|
end
|
114
|
-
|
114
|
+
|
115
115
|
it "should be possible to combine feed_for_batch and entry_for_batch" do
|
116
116
|
feed = GoogleContacts::BaseTester.feed_for_batch
|
117
117
|
feed << @t.entry_for_batch(:update)
|
118
118
|
end
|
119
|
-
|
119
|
+
|
120
120
|
it "should corretly set the batch:operation tag" do
|
121
121
|
%(insert update delete).each do |op|
|
122
122
|
batch = @t.entry_for_batch(op.to_sym)
|
data/spec/proxies/array_spec.rb
CHANGED
@@ -11,12 +11,12 @@ describe GoogleContacts::Proxies::Array do
|
|
11
11
|
@proxy[0].should == 'http://some.group'
|
12
12
|
end
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
describe "without existing entries" do
|
16
16
|
before(:each) do
|
17
17
|
create_proxy_from_xml "<entry></entry>"
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
it "should allow pushing a plain value" do
|
21
21
|
@proxy << 'http://foo'
|
22
22
|
@proxy.should have(1).group
|
@@ -34,7 +34,7 @@ describe GoogleContacts::Proxies::Array do
|
|
34
34
|
@proxy << 'http://foo'
|
35
35
|
@proxy.should have(1).group
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
it "should filter nils" do
|
39
39
|
@proxy << nil
|
40
40
|
@proxy.should have(:no).groups
|
@@ -46,7 +46,7 @@ describe GoogleContacts::Proxies::Array do
|
|
46
46
|
@proxy.should have(:no).groups
|
47
47
|
end
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
describe "knows when it is changed" do
|
51
51
|
before(:each) do
|
52
52
|
create_proxy_from_xml <<-XML
|
@@ -62,31 +62,31 @@ describe GoogleContacts::Proxies::Array do
|
|
62
62
|
@proxy << 'http://foo'
|
63
63
|
}.should change(@proxy, :changed?).from(false).to(true)
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
it "should not be changed when a duplicate is added" do
|
67
67
|
lambda {
|
68
68
|
@proxy << 'http://some.group'
|
69
69
|
}.should_not change(@proxy, :changed?).from(false)
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
it "should not be changed when nils are added" do
|
73
73
|
lambda {
|
74
74
|
@proxy.concat [nil, nil]
|
75
75
|
}.should_not change(@proxy, :changed?).from(false)
|
76
76
|
end
|
77
|
-
|
77
|
+
|
78
78
|
it "should not be influenced by order" do
|
79
79
|
lambda {
|
80
80
|
@proxy.replace ['http://another.group', 'http://some.group']
|
81
81
|
}.should_not change(@proxy, :changed?).from(false)
|
82
82
|
end
|
83
83
|
end
|
84
|
-
|
84
|
+
|
85
85
|
describe "synchronize to xml document" do
|
86
86
|
before(:each) do
|
87
87
|
create_proxy_from_xml "<entry></entry>"
|
88
88
|
end
|
89
|
-
|
89
|
+
|
90
90
|
it "should update the group entries" do
|
91
91
|
@proxy << 'http://another.group'
|
92
92
|
@proxy << 'http://some.group'
|
@@ -96,7 +96,7 @@ describe GoogleContacts::Proxies::Array do
|
|
96
96
|
@proxy.synchronize
|
97
97
|
end
|
98
98
|
end
|
99
|
-
|
99
|
+
|
100
100
|
def create_proxy_from_xml(str)
|
101
101
|
@parent = mock('parent', :xml => Nokogiri::XML.parse(str).root)
|
102
102
|
@proxy = GoogleContacts::Proxies::Array.new(@parent, :tag => 'group', :attr => 'href')
|
data/spec/proxies/emails_spec.rb
CHANGED
@@ -26,42 +26,42 @@ describe GoogleContacts::Proxies::Emails do
|
|
26
26
|
@proxy['fubar@gmail.com' ].rel .should == 'http://schemas.google.com/g/2005#home'
|
27
27
|
@proxy['fubar@gmail.com' ] .should be_primary
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
it "should be able to return the primary address" do
|
31
31
|
@proxy.primary.should == @proxy['fubar@gmail.com']
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
it "should initially be unchanged" do
|
35
35
|
@proxy.changed?.should be_false
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
describe "should be changed" do
|
39
39
|
after(:each) do
|
40
40
|
@proxy.changed?.should be_true
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
it "when switching primary" do
|
44
44
|
@proxy['foo@bar.example.com'].primary!
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
it "when modifying name" do
|
48
48
|
@proxy['foo@bar.example.com'].name = 'Quux'
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
it "when modifying rel" do
|
52
52
|
@proxy['foo@bar.example.com'].rel = 'http://some.rel'
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
it "when adding a new address" do
|
56
56
|
@proxy << 'john@doe.com'
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
it "when removing an address" do
|
60
60
|
@proxy.delete 'foo@bar.example.com'
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
65
|
describe "without existing entries" do
|
66
66
|
before(:each) do
|
67
67
|
create_proxy_from_xml <<-XML
|
@@ -69,7 +69,7 @@ describe GoogleContacts::Proxies::Emails do
|
|
69
69
|
</entry>
|
70
70
|
XML
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
it "should be possible to add email address" do
|
74
74
|
lambda {
|
75
75
|
@proxy['foo@bar.com']
|
@@ -79,24 +79,24 @@ describe GoogleContacts::Proxies::Emails do
|
|
79
79
|
@proxy << 'quux@bar.com'
|
80
80
|
}.should change(@proxy, :size).by(1)
|
81
81
|
end
|
82
|
-
|
82
|
+
|
83
83
|
it "should raise when adding a duplicate" do
|
84
84
|
@proxy << 'quux@bar.com'
|
85
85
|
lambda {
|
86
86
|
@proxy << 'quux@bar.com'
|
87
87
|
}.should raise_error
|
88
88
|
end
|
89
|
-
|
89
|
+
|
90
90
|
it "should provide sensible defaults for new addresses" do
|
91
91
|
@proxy['john@doe.com'].address.should == 'john@doe.com'
|
92
92
|
@proxy['john@doe.com'].rel.should == 'http://schemas.google.com/g/2005#home'
|
93
93
|
@proxy['john@doe.com'].label.should be_nil
|
94
94
|
end
|
95
|
-
|
95
|
+
|
96
96
|
it "should set the first created entry to be primary" do
|
97
97
|
@proxy['john@doe.com'].should be_primary
|
98
98
|
end
|
99
|
-
|
99
|
+
|
100
100
|
it "should only allow one entry to be primary" do
|
101
101
|
@proxy['john@doe.com'].should be_primary
|
102
102
|
@proxy['jane@doe.com'].should_not be_primary
|
@@ -104,7 +104,7 @@ describe GoogleContacts::Proxies::Emails do
|
|
104
104
|
@proxy['john@doe.com'].should_not be_primary
|
105
105
|
@proxy['jane@doe.com'].should be_primary
|
106
106
|
end
|
107
|
-
|
107
|
+
|
108
108
|
it "should only allow either rel or label to be set" do
|
109
109
|
@proxy['john@doe.com'].rel = 'foo'
|
110
110
|
@proxy['john@doe.com'].label = 'foo'
|
@@ -114,13 +114,13 @@ describe GoogleContacts::Proxies::Emails do
|
|
114
114
|
@proxy['john@doe.com'].rel = 'foo'
|
115
115
|
@proxy['john@doe.com'].label.should be_nil
|
116
116
|
end
|
117
|
-
|
117
|
+
|
118
118
|
it "should raise when attempting to modify the address" do
|
119
119
|
lambda {
|
120
120
|
@proxy['john@doe.com'].address = 'foo'
|
121
121
|
}.should raise_error(/cannot modify/i)
|
122
122
|
end
|
123
|
-
|
123
|
+
|
124
124
|
it "should allow email addresses to be removed" do
|
125
125
|
@proxy << 'john@doe.com'
|
126
126
|
lambda {
|
@@ -128,7 +128,7 @@ describe GoogleContacts::Proxies::Emails do
|
|
128
128
|
}.should change(@proxy, :size).from(1).to(0)
|
129
129
|
end
|
130
130
|
end
|
131
|
-
|
131
|
+
|
132
132
|
describe "synchronize to xml document" do
|
133
133
|
before(:each) do
|
134
134
|
create_proxy_from_xml <<-XML
|
@@ -136,18 +136,18 @@ describe GoogleContacts::Proxies::Emails do
|
|
136
136
|
</entry>
|
137
137
|
XML
|
138
138
|
end
|
139
|
-
|
139
|
+
|
140
140
|
it "should clear existing email tags" do
|
141
141
|
@proxy << 'john@doe.com'
|
142
142
|
@parent.expects(:remove_xml).with('./gd:email')
|
143
143
|
@parent.stubs(:insert_xml)
|
144
144
|
@proxy.synchronize
|
145
145
|
end
|
146
|
-
|
146
|
+
|
147
147
|
it "should add every email address" do
|
148
148
|
@proxy << 'john@doe.com'
|
149
149
|
@proxy << 'jane@doe.com'
|
150
|
-
|
150
|
+
|
151
151
|
@parent.stubs(:remove_xml)
|
152
152
|
@parent.expects(:insert_xml).with('gd:email', has_entries(
|
153
153
|
'address' => 'john@doe.com',
|
@@ -157,7 +157,7 @@ describe GoogleContacts::Proxies::Emails do
|
|
157
157
|
@proxy.synchronize
|
158
158
|
end
|
159
159
|
end
|
160
|
-
|
160
|
+
|
161
161
|
def create_proxy_from_xml(str)
|
162
162
|
@parent = stub('parent', :xml => Nokogiri::XML.parse(str).root)
|
163
163
|
@proxy = GoogleContacts::Proxies::Emails.new(@parent)
|
data/spec/proxies/hash_spec.rb
CHANGED
@@ -15,12 +15,12 @@ describe GoogleContacts::Proxies::Hash do
|
|
15
15
|
@proxy.should have(1).entry
|
16
16
|
end
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
describe "without existing entries" do
|
20
20
|
before(:each) do
|
21
21
|
create_proxy_from_xml "<entry></entry>"
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
it "should allow setting a value" do
|
25
25
|
@proxy[:foo] = 'bar'
|
26
26
|
@proxy.should have(1).entry
|
@@ -33,7 +33,7 @@ describe GoogleContacts::Proxies::Hash do
|
|
33
33
|
@proxy.should have(:no).entries
|
34
34
|
end
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
describe "knows when it is changed" do
|
38
38
|
before(:each) do
|
39
39
|
create_proxy_from_xml <<-XML
|
@@ -48,19 +48,19 @@ describe GoogleContacts::Proxies::Hash do
|
|
48
48
|
@proxy[:foo] = 'quux'
|
49
49
|
}.should change(@proxy, :changed?).from(false).to(true)
|
50
50
|
end
|
51
|
-
|
51
|
+
|
52
52
|
it "should not be changed when the new value equals the old one" do
|
53
53
|
lambda {
|
54
54
|
@proxy[:foo] = 'foo'
|
55
55
|
}.should_not change(@proxy, :changed?).from(false)
|
56
56
|
end
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
describe "synchronize to xml document" do
|
60
60
|
before(:each) do
|
61
61
|
create_proxy_from_xml "<entry></entry>"
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
it "should update the group entries" do
|
65
65
|
@proxy[:foo] = 'quux'
|
66
66
|
@proxy[:baz] = 'bar'
|
@@ -70,7 +70,7 @@ describe GoogleContacts::Proxies::Hash do
|
|
70
70
|
@proxy.synchronize
|
71
71
|
end
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
def create_proxy_from_xml(str)
|
75
75
|
@parent = stub('parent', :xml => Nokogiri::XML.parse(str).root)
|
76
76
|
@proxy = GoogleContacts::Proxies::Hash.new(@parent, :tag => 'prop', :key => 'name', :value => 'value')
|
data/spec/proxies/tag_spec.rb
CHANGED
@@ -13,12 +13,12 @@ describe GoogleContacts::Proxies::Tag do
|
|
13
13
|
it "should initialize" do
|
14
14
|
@proxy.should == 'Example'
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
it "should not be changed when initialized" do
|
18
18
|
@proxy.changed?.should be_false
|
19
19
|
end
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
describe "without existing entries" do
|
23
23
|
before(:each) do
|
24
24
|
create_proxy_from_xml <<-XML
|
@@ -26,25 +26,25 @@ describe GoogleContacts::Proxies::Tag do
|
|
26
26
|
</entry>
|
27
27
|
XML
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
it "should initialize the value to nil" do
|
31
31
|
@proxy.nil?.should be_true
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
it "should not create the tag when initializing" do
|
35
35
|
@parent.xml.xpath('./atom:title').should have(:no).entries
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
it "should not be changed when initialized" do
|
39
39
|
@proxy.changed?.should be_false
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
it "should be changed when replace is called" do
|
43
43
|
@proxy.replace("Test")
|
44
44
|
@proxy.changed?.should be_true
|
45
45
|
end
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
describe "synchronize to xml document" do
|
49
49
|
describe "when tag doesn't exist" do
|
50
50
|
before(:each) do
|
@@ -53,7 +53,7 @@ describe GoogleContacts::Proxies::Tag do
|
|
53
53
|
</entry>
|
54
54
|
XML
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
it "should create the tag" do
|
58
58
|
@node = mock('node') { expects(:content=).with('Example') }
|
59
59
|
@parent.expects(:insert_xml).with('atom:title').returns(@node)
|
@@ -61,7 +61,7 @@ describe GoogleContacts::Proxies::Tag do
|
|
61
61
|
@proxy.synchronize
|
62
62
|
end
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
65
|
describe "when tag exists" do
|
66
66
|
before(:each) do
|
67
67
|
create_proxy_from_xml <<-XML
|
@@ -70,7 +70,7 @@ describe GoogleContacts::Proxies::Tag do
|
|
70
70
|
</entry>
|
71
71
|
XML
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
it "should update the tag" do
|
75
75
|
@proxy.replace("Replacement")
|
76
76
|
@proxy.synchronize
|
@@ -78,7 +78,7 @@ describe GoogleContacts::Proxies::Tag do
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
81
|
-
|
81
|
+
|
82
82
|
def create_proxy_from_xml(str)
|
83
83
|
@parent = stub('parent', :xml => Nokogiri::XML.parse(str).root)
|
84
84
|
@proxy = GoogleContacts::Proxies::Tag.new(@parent, :tag => 'atom:title')
|
data/spec/wrapper_spec.rb
CHANGED
@@ -5,38 +5,38 @@ describe GoogleContacts::Wrapper do
|
|
5
5
|
before(:each) do
|
6
6
|
@options = { 'max-results' => 200, 'start-index' => 1 }
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
def params(overrides)
|
10
10
|
@options.merge(overrides).map do |tuple|
|
11
11
|
tuple.join('=')
|
12
12
|
end.join('&')
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
def register(type, options = {})
|
16
16
|
url = "http://www.google.com/m8/feeds/#{type}/default/full?#{params(options)}"
|
17
17
|
FakeWeb.register_uri(:get, url, :body => yield)
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
it "should be able to get list of contacts" do
|
21
21
|
register(:contacts) { asset('contacts_full') }
|
22
22
|
result = wrapper.contacts.find(:all)
|
23
23
|
result.should have(1).contact
|
24
24
|
result.first.should be_a GoogleContacts::Contact
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
it "should be able to get list of contacts when result is paginated" do
|
28
28
|
register(:contacts, 'start-index' => 1) { asset('contacts_full_page1') }
|
29
29
|
register(:contacts, 'start-index' => 26) { asset('contacts_full_page2') }
|
30
30
|
result = wrapper.contacts.find(:all)
|
31
31
|
result.should have(2).contacts
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
it "should be possible to specify the max-results parameter" do
|
35
35
|
register(:contacts, 'max-results' => 25) { asset('contacts_full') }
|
36
36
|
result = wrapper.contacts.find(:all, 'max-results' => 25)
|
37
37
|
result.should have(1).contact
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
it "should be able to get list of groups" do
|
41
41
|
register(:groups) { asset('groups_full') }
|
42
42
|
result = wrapper.groups.find(:all)
|
@@ -44,27 +44,27 @@ describe GoogleContacts::Wrapper do
|
|
44
44
|
result.first.should be_a GoogleContacts::Group
|
45
45
|
end
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
describe "flushing" do
|
49
49
|
it "should not allow nesting of #batch" do
|
50
50
|
lambda {
|
51
51
|
wrapper.batch { wrapper.batch { } }
|
52
52
|
}.should raise_error(/not allowed/i)
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
it "should collect operations in a batch" do
|
56
56
|
wrapper.expects(:post).never
|
57
57
|
document = wrapper.batch(:return_documents => true) do
|
58
58
|
wrapper.contacts.build(:name => 'c1').save
|
59
59
|
wrapper.contacts.build(:name => 'c2').save
|
60
60
|
end.first
|
61
|
-
|
61
|
+
|
62
62
|
document.xpath('.//xmlns:entry').should have(2).entries
|
63
63
|
document.xpath('.//batch:operation').each do |operation|
|
64
64
|
operation['type'].should == 'insert'
|
65
65
|
end
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
it "should flush batches in chunks of 100" do
|
69
69
|
wrapper.expects(:post).with(regexp_matches(%r!/contacts/!), is_a(String)).twice
|
70
70
|
wrapper.batch do
|
@@ -72,12 +72,12 @@ describe GoogleContacts::Wrapper do
|
|
72
72
|
101.times { contact.save }
|
73
73
|
end
|
74
74
|
end
|
75
|
-
|
75
|
+
|
76
76
|
it "should not flush when there are no operations to execute" do
|
77
77
|
wrapper.expects(:post).never
|
78
78
|
wrapper.batch {}
|
79
79
|
end
|
80
|
-
|
80
|
+
|
81
81
|
it "should raise when mixing contacts and groups in one batch" do
|
82
82
|
lambda {
|
83
83
|
wrapper.batch {
|
@@ -86,7 +86,7 @@ describe GoogleContacts::Wrapper do
|
|
86
86
|
}
|
87
87
|
}.should raise_error(/cannot mix/i)
|
88
88
|
end
|
89
|
-
|
89
|
+
|
90
90
|
it "should POST a single-operation batch to contacts when not batching" do
|
91
91
|
wrapper.expects(:post).with(regexp_matches(%r!/contacts/!), is_a(String))
|
92
92
|
wrapper.contacts.build(:name => 'contact').save
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: googlecontacts
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 21
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 0
|
7
8
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
9
|
+
- 7
|
10
|
+
version: 0.1.7
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Pieter Noordhuis
|
@@ -14,16 +15,18 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2010-
|
18
|
+
date: 2010-11-06 00:00:00 +01:00
|
18
19
|
default_executable:
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
21
22
|
name: rspec
|
22
23
|
prerelease: false
|
23
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
24
26
|
requirements:
|
25
27
|
- - ">="
|
26
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 13
|
27
30
|
segments:
|
28
31
|
- 1
|
29
32
|
- 2
|
@@ -35,9 +38,11 @@ dependencies:
|
|
35
38
|
name: fakeweb
|
36
39
|
prerelease: false
|
37
40
|
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
38
42
|
requirements:
|
39
43
|
- - ">="
|
40
44
|
- !ruby/object:Gem::Version
|
45
|
+
hash: 15
|
41
46
|
segments:
|
42
47
|
- 1
|
43
48
|
- 2
|
@@ -49,9 +54,11 @@ dependencies:
|
|
49
54
|
name: mocha
|
50
55
|
prerelease: false
|
51
56
|
requirement: &id003 !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
52
58
|
requirements:
|
53
59
|
- - ">="
|
54
60
|
- !ruby/object:Gem::Version
|
61
|
+
hash: 43
|
55
62
|
segments:
|
56
63
|
- 0
|
57
64
|
- 9
|
@@ -63,9 +70,11 @@ dependencies:
|
|
63
70
|
name: activesupport
|
64
71
|
prerelease: false
|
65
72
|
requirement: &id004 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
66
74
|
requirements:
|
67
75
|
- - ">="
|
68
76
|
- !ruby/object:Gem::Version
|
77
|
+
hash: 11
|
69
78
|
segments:
|
70
79
|
- 2
|
71
80
|
- 3
|
@@ -77,9 +86,11 @@ dependencies:
|
|
77
86
|
name: nokogiri
|
78
87
|
prerelease: false
|
79
88
|
requirement: &id005 !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
80
90
|
requirements:
|
81
91
|
- - ">="
|
82
92
|
- !ruby/object:Gem::Version
|
93
|
+
hash: 5
|
83
94
|
segments:
|
84
95
|
- 1
|
85
96
|
- 4
|
@@ -91,9 +102,11 @@ dependencies:
|
|
91
102
|
name: oauth
|
92
103
|
prerelease: false
|
93
104
|
requirement: &id006 !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
94
106
|
requirements:
|
95
107
|
- - ">="
|
96
108
|
- !ruby/object:Gem::Version
|
109
|
+
hash: 31
|
97
110
|
segments:
|
98
111
|
- 0
|
99
112
|
- 3
|
@@ -153,23 +166,27 @@ rdoc_options:
|
|
153
166
|
require_paths:
|
154
167
|
- lib
|
155
168
|
required_ruby_version: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
156
170
|
requirements:
|
157
171
|
- - ">="
|
158
172
|
- !ruby/object:Gem::Version
|
173
|
+
hash: 3
|
159
174
|
segments:
|
160
175
|
- 0
|
161
176
|
version: "0"
|
162
177
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
178
|
+
none: false
|
163
179
|
requirements:
|
164
180
|
- - ">="
|
165
181
|
- !ruby/object:Gem::Version
|
182
|
+
hash: 3
|
166
183
|
segments:
|
167
184
|
- 0
|
168
185
|
version: "0"
|
169
186
|
requirements: []
|
170
187
|
|
171
188
|
rubyforge_project:
|
172
|
-
rubygems_version: 1.3.
|
189
|
+
rubygems_version: 1.3.7
|
173
190
|
signing_key:
|
174
191
|
specification_version: 3
|
175
192
|
summary: Contacts API on steroids
|