googlecontacts 0.1.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.
- data/.document +5 -0
- data/.gitignore +10 -0
- data/LICENSE +20 -0
- data/README.md +41 -0
- data/README.rdoc +17 -0
- data/Rakefile +49 -0
- data/VERSION +1 -0
- data/lib/google_contacts.rb +15 -0
- data/lib/google_contacts/auth.rb +28 -0
- data/lib/google_contacts/base.rb +163 -0
- data/lib/google_contacts/contact.rb +32 -0
- data/lib/google_contacts/group.rb +9 -0
- data/lib/google_contacts/proxies/array.rb +46 -0
- data/lib/google_contacts/proxies/emails.rb +125 -0
- data/lib/google_contacts/proxies/hash.rb +41 -0
- data/lib/google_contacts/wrapper.rb +126 -0
- data/spec/assets/contacts_full.xml +60 -0
- data/spec/assets/groups_full.xml +58 -0
- data/spec/base_spec.rb +78 -0
- data/spec/contact_spec.rb +80 -0
- data/spec/group_spec.rb +18 -0
- data/spec/proxies/array_spec.rb +105 -0
- data/spec/proxies/emails_spec.rb +161 -0
- data/spec/proxies/hash_spec.rb +78 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +35 -0
- data/spec/wrapper_spec.rb +75 -0
- metadata +129 -0
@@ -0,0 +1,125 @@
|
|
1
|
+
module GoogleContacts
|
2
|
+
module Proxies
|
3
|
+
class Emails < BlankSlate
|
4
|
+
def initialize(parent)
|
5
|
+
@parent = parent
|
6
|
+
reinitialize
|
7
|
+
end
|
8
|
+
|
9
|
+
def reinitialize
|
10
|
+
@current = ::Hash[*@parent.xml.xpath("./gd:email").map do |entry|
|
11
|
+
email = Email.new(self, entry.attributes)
|
12
|
+
[email.address, email]
|
13
|
+
end.flatten]
|
14
|
+
|
15
|
+
# create a deep copy
|
16
|
+
@new = ::Hash[*@current.map do |k,v|
|
17
|
+
[k.dup, v.dup]
|
18
|
+
end.flatten]
|
19
|
+
end
|
20
|
+
|
21
|
+
def changed?
|
22
|
+
@current != @new
|
23
|
+
end
|
24
|
+
|
25
|
+
def primary!(address)
|
26
|
+
@new.each do |key, email|
|
27
|
+
if key == address
|
28
|
+
email.primary = true
|
29
|
+
else
|
30
|
+
email.delete(:primary)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def <<(address)
|
36
|
+
raise "Duplicate address" if @new[address]
|
37
|
+
add(address)
|
38
|
+
end
|
39
|
+
|
40
|
+
def [](address)
|
41
|
+
@new[address] || add(address)
|
42
|
+
end
|
43
|
+
|
44
|
+
def synchronize
|
45
|
+
@parent.remove_xml("./gd:email")
|
46
|
+
@new.each_pair do |address, email|
|
47
|
+
@parent.insert_xml('gd:email', email)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
def add(address)
|
53
|
+
set_primary = @new.empty?
|
54
|
+
@new[address] = Email.new(self, { :address => address })
|
55
|
+
@new[address].primary = true if set_primary
|
56
|
+
@new[address]
|
57
|
+
end
|
58
|
+
|
59
|
+
def method_missing(sym, *args, &blk)
|
60
|
+
if [:size, :delete].include?(sym)
|
61
|
+
@new.send(sym, *args, &blk)
|
62
|
+
else
|
63
|
+
super
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class Email < ::HashWithIndifferentAccess
|
68
|
+
DEFAULTS = {
|
69
|
+
:rel => 'http://schemas.google.com/g/2005#home'
|
70
|
+
}.freeze
|
71
|
+
|
72
|
+
alias_attribute :name, :displayName
|
73
|
+
|
74
|
+
def initialize(parent, attributes = {})
|
75
|
+
super(DEFAULTS)
|
76
|
+
@parent = parent
|
77
|
+
|
78
|
+
attributes.each do |key, value|
|
79
|
+
send("#{key}=", value)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def primary!
|
84
|
+
@parent.primary! self[:address]
|
85
|
+
end
|
86
|
+
|
87
|
+
def rel=(arg)
|
88
|
+
delete(:label)
|
89
|
+
method_missing("rel=", arg)
|
90
|
+
end
|
91
|
+
|
92
|
+
def label=(arg)
|
93
|
+
delete(:rel)
|
94
|
+
method_missing("label=", arg)
|
95
|
+
end
|
96
|
+
|
97
|
+
def []=(key, value)
|
98
|
+
if "#{key}" == 'address' && self[key]
|
99
|
+
raise "Cannot modify email address"
|
100
|
+
end
|
101
|
+
super(key, value.to_s)
|
102
|
+
end
|
103
|
+
|
104
|
+
def dup
|
105
|
+
self.class.new(@parent, self)
|
106
|
+
end
|
107
|
+
|
108
|
+
def method_missing(sym, *args, &blk)
|
109
|
+
if sym.to_s =~ /^(\w+)(=|\?)?$/
|
110
|
+
case $2
|
111
|
+
when '='
|
112
|
+
send(:[]=, $1, *args)
|
113
|
+
when '?'
|
114
|
+
send(:[], $1) == 'true'
|
115
|
+
else
|
116
|
+
send(:[], $1)
|
117
|
+
end
|
118
|
+
else
|
119
|
+
super
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end # class Email
|
123
|
+
end # class Emails
|
124
|
+
end # module Proxies
|
125
|
+
end # module GoogleContacts
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module GoogleContacts
|
2
|
+
module Proxies
|
3
|
+
class Hash < BlankSlate
|
4
|
+
def initialize(parent, options)
|
5
|
+
@parent = parent
|
6
|
+
@tag = options[:tag]
|
7
|
+
@key = options[:key]
|
8
|
+
@value = options[:value]
|
9
|
+
|
10
|
+
reinitialize
|
11
|
+
end
|
12
|
+
|
13
|
+
def reinitialize
|
14
|
+
@current = HashWithIndifferentAccess.new
|
15
|
+
@parent.xml.xpath("./#{@tag}").map do |entry|
|
16
|
+
@current[entry[@key]] = entry[@value]
|
17
|
+
end
|
18
|
+
|
19
|
+
# create a deep copy
|
20
|
+
@new = HashWithIndifferentAccess.new
|
21
|
+
@current.each { |k,v| @new[k.dup] = v.dup }
|
22
|
+
end
|
23
|
+
|
24
|
+
def changed?
|
25
|
+
@current != @new
|
26
|
+
end
|
27
|
+
|
28
|
+
def synchronize
|
29
|
+
@parent.remove_xml("./#{@tag}")
|
30
|
+
@new.each_pair do |key, value|
|
31
|
+
@parent.insert_xml(@tag, @key => key, @value => value)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
def method_missing(sym, *args, &blk)
|
37
|
+
@new.send(sym, *args, &blk)
|
38
|
+
end
|
39
|
+
end # class Hash
|
40
|
+
end # module Proxies
|
41
|
+
end # module GoogleContacts
|
@@ -0,0 +1,126 @@
|
|
1
|
+
module GoogleContacts
|
2
|
+
class Wrapper
|
3
|
+
attr_reader :consumer
|
4
|
+
|
5
|
+
CONTACTS_BATCH = "http://www.google.com/m8/feeds/contacts/default/full/batch".freeze
|
6
|
+
GROUPS_BATCH = "http://www.google.com/m8/feeds/groups/default/full/batch".freeze
|
7
|
+
|
8
|
+
# Proxies for crud
|
9
|
+
attr_reader :contacts
|
10
|
+
attr_reader :groups
|
11
|
+
|
12
|
+
def initialize(consumer)
|
13
|
+
@consumer = consumer
|
14
|
+
|
15
|
+
@contacts = CollectionProxy.new(self, 'contacts')
|
16
|
+
@groups = CollectionProxy.new(self, 'groups')
|
17
|
+
end
|
18
|
+
|
19
|
+
def get(url, options = {})
|
20
|
+
query = options.map { |k,v| "#{k}=#{v}" }.join('&')
|
21
|
+
url += "?#{query}" if query.size > 0
|
22
|
+
|
23
|
+
body = consumer.get(url).body
|
24
|
+
Nokogiri::XML.parse body
|
25
|
+
end
|
26
|
+
|
27
|
+
def post(url, body)
|
28
|
+
consumer.post(url, body, 'Content-Type' => 'application/atom+xml')
|
29
|
+
end
|
30
|
+
|
31
|
+
def batch(options = {}, &blk)
|
32
|
+
raise "Nesting of calls to batch is not allowed" if @batching
|
33
|
+
@batching = true
|
34
|
+
@batch ||= []
|
35
|
+
|
36
|
+
yield(blk)
|
37
|
+
@batching = false
|
38
|
+
|
39
|
+
# create documents to be flushed
|
40
|
+
documents = @batch.each_slice(100).map do |chunk|
|
41
|
+
batch_document(chunk)
|
42
|
+
end
|
43
|
+
@batch.clear
|
44
|
+
|
45
|
+
if options[:return_documents]
|
46
|
+
documents
|
47
|
+
else
|
48
|
+
documents.each do |doc|
|
49
|
+
flush_batch(doc)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def find(what, options = {}, &blk)
|
55
|
+
xml = get("http://www.google.com/m8/feeds/#{what}/default/full", options)
|
56
|
+
xml.xpath('/xmlns:feed/xmlns:entry').map(&blk)
|
57
|
+
end
|
58
|
+
|
59
|
+
def save(instance)
|
60
|
+
entry = instance.entry_for_batch(instance.new? ? :insert : :update)
|
61
|
+
append_to_batch(entry)
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def append_to_batch(entry)
|
67
|
+
if @batching
|
68
|
+
if @batch.present?
|
69
|
+
# puts @batch.last.a
|
70
|
+
# puts @batch.last.at('./category').inspect
|
71
|
+
batch_term = @batch.last.at('./category')['term']
|
72
|
+
entry_term = entry.at('./category')['term']
|
73
|
+
raise "Cannot mix Contact and Group in one batch" if batch_term != entry_term
|
74
|
+
end
|
75
|
+
|
76
|
+
@batch << entry
|
77
|
+
else
|
78
|
+
batch do
|
79
|
+
@batch << entry
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Use the <category/> tag of the first entry to find out
|
85
|
+
# which type we're flushing
|
86
|
+
def flush_batch(document)
|
87
|
+
url = case document.at('./xmlns:entry[1]/xmlns:category')['term']
|
88
|
+
when /#contact$/i
|
89
|
+
CONTACTS_BATCH
|
90
|
+
when /#group$/i
|
91
|
+
GROUPS_BATCH
|
92
|
+
else
|
93
|
+
raise "Unable to determine type for batch"
|
94
|
+
end
|
95
|
+
post(url, document.to_xml)
|
96
|
+
end
|
97
|
+
|
98
|
+
def batch_document(*operations)
|
99
|
+
batch_feed = Base.feed_for_batch
|
100
|
+
operations.flatten.each do |operation|
|
101
|
+
batch_feed << operation
|
102
|
+
end
|
103
|
+
batch_feed
|
104
|
+
end
|
105
|
+
|
106
|
+
class CollectionProxy
|
107
|
+
def initialize(wrapper, collection)
|
108
|
+
@wrapper = wrapper
|
109
|
+
@collection = collection
|
110
|
+
@klass = collection.singularize.camelcase.constantize
|
111
|
+
end
|
112
|
+
|
113
|
+
# :what - all, ID, whatever, currently unused
|
114
|
+
def find(what, options = {})
|
115
|
+
@wrapper.find(@collection, options) do |entry|
|
116
|
+
@klass.new(@wrapper, entry)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def build(attributes = {})
|
121
|
+
@klass.new(@wrapper)
|
122
|
+
end
|
123
|
+
|
124
|
+
end # class CollectionProxy
|
125
|
+
end # class Wrapper
|
126
|
+
end # module GoogleContacts
|
@@ -0,0 +1,60 @@
|
|
1
|
+
<feed xmlns='http://www.w3.org/2005/Atom'
|
2
|
+
xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/'
|
3
|
+
xmlns:gContact='http://schemas.google.com/contact/2008'
|
4
|
+
xmlns:batch='http://schemas.google.com/gdata/batch'
|
5
|
+
xmlns:gd='http://schemas.google.com/g/2005'
|
6
|
+
gd:etag='W/"CUMBRHo_fip7ImA9WxRbGU0."'>
|
7
|
+
<id>liz@gmail.com</id>
|
8
|
+
<updated>2008-12-10T10:04:15.446Z</updated>
|
9
|
+
<category scheme='http://schemas.google.com/g/2005#kind'
|
10
|
+
term='http://schemas.google.com/contact/2008#contact' />
|
11
|
+
<title>Elizabeth Bennet's Contacts</title>
|
12
|
+
<link rel='http://schemas.google.com/g/2005#feed'
|
13
|
+
type='application/atom+xml'
|
14
|
+
href='http://www.google.com/m8/feeds/contacts/liz%40gmail.com/full' />
|
15
|
+
<link rel='http://schemas.google.com/g/2005#post'
|
16
|
+
type='application/atom+xml'
|
17
|
+
href='http://www.google.com/m8/feeds/contacts/liz%40gmail.com/full' />
|
18
|
+
<link rel='http://schemas.google.com/g/2005#batch'
|
19
|
+
type='application/atom+xml'
|
20
|
+
href='http://www.google.com/m8/feeds/contacts/liz%40gmail.com/full/batch' />
|
21
|
+
<link rel='self' type='application/atom+xml'
|
22
|
+
href='http://www.google.com/m8/feeds/contacts/liz%40gmail.com/full?max-results=25' />
|
23
|
+
<author>
|
24
|
+
<name>Elizabeth Bennet</name>
|
25
|
+
<email>liz@gmail.com</email>
|
26
|
+
</author>
|
27
|
+
<generator version='1.0' uri='http://www.google.com/m8/feeds'>
|
28
|
+
Contacts
|
29
|
+
</generator>
|
30
|
+
<openSearch:totalResults>1</openSearch:totalResults>
|
31
|
+
<openSearch:startIndex>1</openSearch:startIndex>
|
32
|
+
<openSearch:itemsPerPage>25</openSearch:itemsPerPage>
|
33
|
+
<entry gd:etag='"Qn04eTVSLyp7ImA9WxRbGEUORAQ."'>
|
34
|
+
<id>
|
35
|
+
http://www.google.com/m8/feeds/contacts/liz%40gmail.com/base/c9012de
|
36
|
+
</id>
|
37
|
+
<updated>2008-12-10T04:45:03.331Z</updated>
|
38
|
+
<app:edited xmlns:app='http://www.w3.org/2007/app'>2008-12-10T04:45:03.331Z</app:edited>
|
39
|
+
<category scheme='http://schemas.google.com/g/2005#kind'
|
40
|
+
term='http://schemas.google.com/contact/2008#contact' />
|
41
|
+
<title>Fitzwilliam Darcy</title>
|
42
|
+
<gd:name>
|
43
|
+
<gd:fullName>Fitzwilliam Darcy</gd:fullName>
|
44
|
+
</gd:name>
|
45
|
+
<link rel='http://schemas.google.com/contacts/2008/rel#photo' type='image/*'
|
46
|
+
href='http://www.google.com/m8/feeds/photos/media/liz%40gmail.com/c9012de'
|
47
|
+
gd:etag='"KTlcZWs1bCp7ImBBPV43VUV4LXEZCXERZAc."' />
|
48
|
+
<link rel='self' type='application/atom+xml'
|
49
|
+
href='http://www.google.com/m8/feeds/contacts/liz%40gmail.com/full/c9012de' />
|
50
|
+
<link rel='edit' type='application/atom+xml'
|
51
|
+
href='http://www.google.com/m8/feeds/contacts/liz%40gmail.com/full/c9012de' />
|
52
|
+
<gd:phoneNumber rel='http://schemas.google.com/g/2005#home'
|
53
|
+
primary='true'>
|
54
|
+
456
|
55
|
+
</gd:phoneNumber>
|
56
|
+
<gd:extendedProperty name='pet' value='hamster' />
|
57
|
+
<gContact:groupMembershipInfo deleted='false'
|
58
|
+
href='http://www.google.com/m8/feeds/groups/liz%40gmail.com/base/270f' />
|
59
|
+
</entry>
|
60
|
+
</feed>
|
@@ -0,0 +1,58 @@
|
|
1
|
+
<feed xmlns='http://www.w3.org/2005/Atom'
|
2
|
+
xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/'
|
3
|
+
xmlns:gContact='http://schemas.google.com/contact/2008'
|
4
|
+
xmlns:batch='http://schemas.google.com/gdata/batch'
|
5
|
+
xmlns:gd='http://schemas.google.com/g/2005'
|
6
|
+
gd:etag='W/"D08MQnc-fSp7ImA9WxRbGU0."'>
|
7
|
+
<id>jo@gmail.com</id>
|
8
|
+
<updated>2008-12-10T10:44:43.955Z</updated>
|
9
|
+
<category scheme='http://schemas.google.com/g/2005#kind'
|
10
|
+
term='http://schemas.google.com/contact/2008#group' />
|
11
|
+
<title>Jo March's Contact Groups</title>
|
12
|
+
<link rel='alternate' type='text/html'
|
13
|
+
href='http://www.google.com/' />
|
14
|
+
<link rel='http://schemas.google.com/g/2005#feed'
|
15
|
+
type='application/atom+xml'
|
16
|
+
href='http://www.google.com/m8/feeds/groups/jo%40gmail.com/thin' />
|
17
|
+
<link rel='http://schemas.google.com/g/2005#post'
|
18
|
+
type='application/atom+xml'
|
19
|
+
href='http://www.google.com/m8/feeds/groups/jo%40gmail.com/thin' />
|
20
|
+
<link rel='http://schemas.google.com/g/2005#batch'
|
21
|
+
type='application/atom+xml'
|
22
|
+
href='http://www.google.com/m8/feeds/groups/jo%40gmail.com/thin/batch' />
|
23
|
+
<link rel='self'
|
24
|
+
type='application/atom+xml'
|
25
|
+
href='http://www.google.com/m8/feeds/groups/jo%40gmail.com/thin?max-results=25' />
|
26
|
+
<author>
|
27
|
+
<name>Jo March</name>
|
28
|
+
<email>jo@gmail.com</email>
|
29
|
+
</author>
|
30
|
+
<generator version='1.0'
|
31
|
+
uri='http://www.google.com/m8/feeds'>Contacts</generator>
|
32
|
+
<openSearch:totalResults>5</openSearch:totalResults>
|
33
|
+
<openSearch:startIndex>1</openSearch:startIndex>
|
34
|
+
<openSearch:itemsPerPage>25</openSearch:itemsPerPage>
|
35
|
+
<entry gd:etag='"YDwqeyI."'>
|
36
|
+
<id>http://www.google.com/m8/feeds/groups/jo%40gmail.com/base/6</id>
|
37
|
+
<updated>1970-01-01T00:00:00.000Z</updated>
|
38
|
+
<category scheme='http://schemas.google.com/g/2005#kind'
|
39
|
+
term='http://schemas.google.com/contact/2008#group' />
|
40
|
+
<title>System Group: My Contacts</title>
|
41
|
+
<content>System Group: My Contacts</content>
|
42
|
+
<link rel='self' type='application/atom+xml'
|
43
|
+
href='http://www.google.com/m8/feeds/groups/jo%40gmail.com/thin/6' />
|
44
|
+
<gContact:systemGroup id='Contacts' />
|
45
|
+
</entry>
|
46
|
+
<entry gd:etag='"Rn05fDVSLyp7ImA9WxRbGEUORQM."'>
|
47
|
+
<id>http://www.google.com/m8/feeds/groups/jo%40gmail.com/base/68f415478ba1aa69</id>
|
48
|
+
<updated>2008-12-10T04:44:37.324Z</updated>
|
49
|
+
<category scheme='http://schemas.google.com/g/2005#kind'
|
50
|
+
term='http://schemas.google.com/contact/2008#group' />
|
51
|
+
<title>joggers</title>
|
52
|
+
<content>joggers</content>
|
53
|
+
<link rel='self' type='application/atom+xml'
|
54
|
+
href='http://www.google.com/m8/feeds/groups/jo%40gmail.com/thin/68f415478ba1aa69' />
|
55
|
+
<link rel='edit' type='application/atom+xml'
|
56
|
+
href='http://www.google.com/m8/feeds/groups/jo%40gmail.com/thin/68f415478ba1aa69' />
|
57
|
+
</entry>
|
58
|
+
</feed>
|
data/spec/base_spec.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
class BaseTester < Base
|
4
|
+
CATEGORY_TERM = "i'm not used here"
|
5
|
+
end
|
6
|
+
|
7
|
+
describe Base do
|
8
|
+
it "should not be possible to create" do
|
9
|
+
lambda {
|
10
|
+
Base.new(wrapper, 'some xml')
|
11
|
+
}.should raise_error(/cannot create instance/i)
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "with an XML document" do
|
15
|
+
before(:each) do
|
16
|
+
@t = BaseTester.new(wrapper)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should default namespace to document default" do
|
20
|
+
node = @t.insert_xml 'tag'
|
21
|
+
node.namespace.href.should == 'http://www.w3.org/2005/Atom'
|
22
|
+
@t.xpath('xmlns:tag').should have(1).node
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should set namespace when specified in tag" do
|
26
|
+
node = @t.insert_xml 'gd:extendedProperty'
|
27
|
+
node.namespace.href.should == 'http://schemas.google.com/g/2005'
|
28
|
+
@t.xpath('gd:extendedProperty').should have(1).node
|
29
|
+
|
30
|
+
node = @t.insert_xml 'gContact:birthday'
|
31
|
+
node.namespace.href.should == 'http://schemas.google.com/contact/2008'
|
32
|
+
@t.xpath('gContact:birthday').should have(1).node
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should raise on unknown namespace" do
|
36
|
+
lambda {
|
37
|
+
@t.insert_xml 'unknown:foo'
|
38
|
+
}.should raise_error(/unknown namespace/i)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should also set attributes if given" do
|
42
|
+
node = @t.insert_xml 'tag', :foo => 'bar'
|
43
|
+
node['foo'].should == 'bar'
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should allow removing xml" do
|
47
|
+
@t.insert_xml 'gd:extendedProperty'
|
48
|
+
@t.xpath('./gd:extendedProperty').should have(1).node
|
49
|
+
|
50
|
+
@t.remove_xml 'gd:extendedProperty'
|
51
|
+
@t.xpath('./gd:extendedProperty').should have(:no).nodes
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "prepare for batch operation" do
|
56
|
+
before(:all) do
|
57
|
+
@t = BaseTester.new(wrapper, parsed_asset('contacts_full').at('feed > entry'))
|
58
|
+
@batch = @t.entry_for_batch(:update)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should not share the same document" do
|
62
|
+
@batch.document.should_not == @t.xml.document
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should create a duplicate node without link tags" do
|
66
|
+
@batch.xpath('./xmlns:link').should be_empty
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should remove the updated tag (not useful when updating)" do
|
70
|
+
@batch.xpath('./xmlns:updated').should be_empty
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should be possible to combine feed_for_batch and entry_for_batch" do
|
74
|
+
feed = BaseTester.feed_for_batch
|
75
|
+
feed << @t.entry_for_batch(:update)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|