pezra-contacts 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.
@@ -0,0 +1,73 @@
1
+ # FakeWeb - Ruby Helper for Faking Web Requests
2
+ # Copyright 2006 Blaine Cook <romeda@gmail.com>.
3
+ #
4
+ # FakeWeb is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # FakeWeb is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with FakeWeb; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ require 'net/http'
19
+ require 'net/https'
20
+ require 'stringio'
21
+
22
+ module Net #:nodoc:
23
+
24
+ class BufferedIO #:nodoc:
25
+ def initialize( io, debug_output = nil )
26
+ @debug_output = debug_output
27
+ @io = case io
28
+ when Socket, IO: io
29
+ when String
30
+ File.exists?(io) ? File.open(io, "r") : StringIO.new(io)
31
+ end
32
+ raise "Unable to create local socket" unless @io
33
+ connect
34
+ end
35
+
36
+ def connect(*args)
37
+ @rbuf = ''
38
+ end
39
+
40
+ def rbuf_fill
41
+ @rbuf << @io.sysread(1024)
42
+ end
43
+ end
44
+
45
+ class HTTP #:nodoc:
46
+
47
+ def HTTP.socket_type #:nodoc:
48
+ FakeWeb::SocketDelegator
49
+ end
50
+
51
+ alias :original_net_http_request :request
52
+ alias :original_net_http_connect :connect
53
+
54
+ def request(req, body = nil, &block)
55
+ prot = use_ssl ? "https" : "http"
56
+ uri = "#{prot}://#{self.address}#{req.path}"
57
+ uri, query_string = uri.split('?')
58
+ query_string = body unless req.method == 'GET'
59
+
60
+ if FakeWeb.registered_uri?(uri)
61
+ @socket = Net::HTTP.socket_type.new
62
+ return FakeWeb.response_for(uri, query_string, req, &block)
63
+ else
64
+ # original_net_http_connect
65
+ # return original_net_http_request(req, body, &block)
66
+ raise "unexpected HTTP #{req.method} to #{uri}"
67
+ end
68
+ end
69
+
70
+ def connect
71
+ end
72
+ end
73
+ end
data/spec/fake_web.rb ADDED
@@ -0,0 +1,279 @@
1
+ # FakeWeb - Ruby Helper for Faking Web Requests
2
+ # Copyright 2006 Blaine Cook <romeda@gmail.com>.
3
+ #
4
+ # FakeWeb is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # FakeWeb is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with FakeWeb; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ require 'fake_net_http'
19
+ require 'singleton'
20
+ require 'cgi'
21
+
22
+ module OpenURI #:nodoc: all
23
+ class HTTPError < StandardError; end;
24
+ end
25
+
26
+ module FakeWeb
27
+
28
+ # Resets the FakeWeb Registry. This will force all subsequent web requests to
29
+ # behave as real requests.
30
+ def FakeWeb.clean_registry; FakeWeb::Registry.instance.clean_registry; end
31
+
32
+ # Register +uri+ to be handled according to +options+. +uri+ can be a
33
+ # +String+ or an +URI+ object. +options+ must be a +Hash+ that must contain
34
+ # any one of the following keys:
35
+ #
36
+ # <tt>:string</tt>::
37
+ # Takes a +String+ argument that is returned as the body of the response.
38
+ # FakeWeb.register_uri('http://example.com/', :string => "Hello World!")
39
+ # <tt>:file</tt>::
40
+ # Takes a valid filesystem path to a file that is slurped and returned as
41
+ # the body of the response.
42
+ # FakeWeb.register_uri('http://example.com/', :file => "/tmp/my_response_body.txt")
43
+ # <tt>:response</tt>::
44
+ # Either an <tt>Net::HTTPResponse</tt>, an +IO+ or a +String+.
45
+ #
46
+ # The easier way by far is to pass the <tt>:response</tt> option to
47
+ # +register_uri+ as a +String+ or an (open for reads) +IO+ object which
48
+ # will be used as the complete HTTP response, including headers and body.
49
+ # If the string points to a readable file, this file will be used as the
50
+ # content for the request.
51
+ #
52
+ # To obtain a complete response document, you can use the +curl+ command,
53
+ # like so:
54
+ #
55
+ # curl -i http://www.example.com/ > response_for_www.example.com
56
+ #
57
+ # which can then be used in your test environment like so:
58
+ #
59
+ # FakeWeb.register_uri('http://www.example.com/', :response => 'response_for_www.example.com')
60
+ #
61
+ # See the <tt>Net::HTTPResponse</tt>
62
+ # documentation[http://ruby-doc.org/stdlib/libdoc/net/http/rdoc/classes/Net/HTTPResponse.html]
63
+ # for more information on creating custom response objects.
64
+ #
65
+ # Two optional arguments are also accepted:
66
+ #
67
+ # <tt>:status</tt>::
68
+ # Passing <tt>:status</tt> as a two-value array will set the response code
69
+ # and message. The defaults are <tt>200</tt> and <tt>OK</tt>, respectively.
70
+ # Example:
71
+ # FakeWeb.register_uri('http://www.example.com/', :response => "Go away!", :status => [ 404, "Not Found" ])
72
+ # <tt>:exception</tt>::
73
+ # The argument passed via <tt>:exception</tt> will be raised when the
74
+ # specified URL is requested. Any +Exception+ class is valid. Example:
75
+ # FakeWeb.register_uri('http://www.example.com/', :exception => Net::HTTPError)
76
+ #
77
+ def FakeWeb.register_uri(uri, options); FakeWeb::Registry.instance.register_uri(uri, options); end
78
+
79
+ # Returns the faked Net::HTTPResponse object associated with +uri+.
80
+ def FakeWeb.response_for(uri, query_string, req, &block) #:nodoc: :yields: response
81
+ FakeWeb::Registry.instance.response_for(uri, query_string, req, &block)
82
+ end
83
+
84
+ # Checks for presence of +uri+ in the +FakeWeb+ registry.
85
+ def FakeWeb.registered_uri?(uri); FakeWeb::Registry.instance.registered_uri?(uri); end
86
+
87
+ class Registry #:nodoc:
88
+ include Singleton
89
+
90
+ attr_accessor :uri_map
91
+
92
+ def initialize
93
+ clean_registry
94
+ end
95
+
96
+ def clean_registry
97
+ self.uri_map = {}
98
+ end
99
+
100
+ def register_uri(uri, options)
101
+ uri_map[normalize_uri(uri)] = FakeWeb::Responder.new(uri, options)
102
+ end
103
+
104
+ def registered_uri?(uri)
105
+ uri_map.has_key?(normalize_uri(uri))
106
+ end
107
+
108
+ def registered_uri(uri)
109
+ uri = normalize_uri(uri)
110
+ return uri_map[uri] if registered_uri?(uri)
111
+ end
112
+
113
+ def response_for(uri, query_string, req, &block)
114
+ match = registered_uri(uri)
115
+ compare_methods(match, req)
116
+ compare_queries(match, query_string)
117
+ match.response(req, &block)
118
+ end
119
+
120
+ private
121
+
122
+ def compare_methods(registered, req)
123
+ unless registered.method == req.method
124
+ raise "HTTP method mismatch; expected #{registered.method}, got #{req.method} on #{registered.uri}"
125
+ end
126
+ end
127
+
128
+ def compare_queries(registered, query_string)
129
+ expected_query = registered.options[:query]
130
+ real_query = parse_query(query_string)
131
+
132
+ eql = if expected_query.respond_to?(:keys) and real_query.respond_to?(:keys)
133
+ (registered.options[:query_partial_match] or expected_query.size == real_query.size) and
134
+ expected_query.all? { |key, value| real_query[key.to_s] == value }
135
+ else
136
+ expected_query == real_query
137
+ end
138
+
139
+ unless eql
140
+ raise "query string mismatch; expected #{expected_query.inspect}, got #{real_query.inspect} on #{registered.uri}"
141
+ end
142
+ end
143
+
144
+ def parse_query(query_string)
145
+ if query_string
146
+ CGI::parse(query_string).inject({}) do |params, pair|
147
+ params[pair.first] = pair.last.first
148
+ params
149
+ end
150
+ end
151
+ end
152
+
153
+ def normalize_uri(uri)
154
+ case uri
155
+ when URI: uri
156
+ else
157
+ uri = 'http://' + uri unless uri.match('^https?://')
158
+ URI.parse(uri)
159
+ end
160
+ end
161
+ end
162
+
163
+ module Response #:nodoc:
164
+ def read_body(*args, &block)
165
+ yield @body if block_given?
166
+ @body
167
+ end
168
+ end
169
+
170
+ class Responder #:nodoc:
171
+
172
+ attr_accessor :uri, :options
173
+
174
+ def initialize(uri, options)
175
+ self.uri = uri
176
+ self.options = options
177
+ end
178
+
179
+ def method
180
+ options[:method] || 'GET'
181
+ end
182
+
183
+ def response(req, &block)
184
+ verify_request(req)
185
+
186
+ if has_baked_response?
187
+ response = baked_response
188
+ else
189
+ code, msg = meta_information
190
+ response = Net::HTTPResponse.send(:response_class, code.to_s).new(uri, code.to_s, msg)
191
+ response.instance_variable_set(:@body, content)
192
+ end
193
+ response.instance_variable_set(:@read, true)
194
+ response.extend FakeWeb::Response
195
+
196
+ optionally_raise(response)
197
+
198
+ yield response if block_given?
199
+
200
+ response
201
+ end
202
+
203
+ private
204
+
205
+ def content
206
+ [ :file, :string ].each do |map_option|
207
+ next unless options.has_key?(map_option)
208
+ return self.send("#{map_option}_response", options[map_option])
209
+ end
210
+
211
+ return ''
212
+ end
213
+
214
+ def file_response(path)
215
+ IO.readlines(path).join("\n")
216
+ end
217
+
218
+ def string_response(string)
219
+ string
220
+ end
221
+
222
+ def baked_response
223
+ resp = case options[:response]
224
+ when Net::HTTPResponse: options[:response]
225
+ when String
226
+ socket = Net::BufferedIO.new(options[:response])
227
+ r = Net::HTTPResponse.read_new(socket)
228
+ r.instance_eval { @header['transfer-encoding'] = nil }
229
+ r.reading_body(socket, true) {}
230
+ r
231
+ else raise StandardError, "Handler unimplemented for response #{options[:response]}"
232
+ end
233
+ end
234
+
235
+ def has_baked_response?
236
+ options.has_key?(:response)
237
+ end
238
+
239
+ def optionally_raise(response)
240
+ return unless options.has_key?(:exception)
241
+ ex_alloc = options[:exception].allocate
242
+ ex_instance = case ex_alloc
243
+ when Net::HTTPError, OpenURI::HTTPError: options[:exception].new('Exception from FakeWeb', response)
244
+ else options[:exception].new
245
+ end
246
+ raise ex_instance
247
+ end
248
+
249
+ def meta_information
250
+ if options.has_key?(:status); options[:status]
251
+ else; [ 200, 'OK' ]
252
+ end
253
+ end
254
+
255
+ def verify_request(req)
256
+ return unless options.has_key?(:verify)
257
+ options[:verify].call(req)
258
+ end
259
+ end
260
+
261
+ class SocketDelegator #:nodoc:
262
+
263
+ def initialize(delegate=nil)
264
+ @delegate = nil
265
+ end
266
+
267
+ def method_missing(method, *args, &block)
268
+ return @delegate.send(method, *args, &block) if @delegate
269
+ return self.send("my_#{method}", *args, &block)
270
+ end
271
+
272
+ def my_closed?
273
+ @closed ||= true
274
+ end
275
+
276
+ def my_readuntil(*args)
277
+ end
278
+ end
279
+ end
@@ -0,0 +1,10 @@
1
+ windows_live:
2
+ appid: your_app_id
3
+ secret: your_app_secret_key
4
+ security_algorithm: wsignin1.0
5
+ return_url: http://yourserver.com/your_return_url
6
+ policy_url: http://yourserver.com/you_policy_url
7
+
8
+ yahoo:
9
+ appid: i%3DB%26p%3DUw70JGIdHWVRbpqYItcMw--
10
+ secret: a34f389cbd135de4618eed5e23409d34450
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <frob>934-746563215463214621</frob>
4
+ </rsp>
@@ -0,0 +1,5 @@
1
+ <auth>
2
+ <token>45-76598454353455</token>
3
+ <perms>read</perms>
4
+ <user nsid="12037949754@N01" username="Bees" fullname="Cal H" />
5
+ </auth>
@@ -0,0 +1,48 @@
1
+ <feed>
2
+ <entry xmlns='http://www.w3.org/2005/Atom' xmlns:gd='http://schemas.google.com/g/2005'>
3
+ <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/contact/2008#contact'/>
4
+ <title>Elizabeth Bennet</title>
5
+ <content>My good friend, Liz. A little quick to judge sometimes, but nice girl.</content>
6
+ <gd:email rel='http://schemas.google.com/g/2005#work' primary='true' address='liz@gmail.com'/>
7
+ <gd:email rel='http://schemas.google.com/g/2005#home' address='liz@example.org'/>
8
+ <gd:phoneNumber rel='http://schemas.google.com/g/2005#work' primary='true'>
9
+ (206)555-1212
10
+ </gd:phoneNumber>
11
+ <gd:phoneNumber rel='http://schemas.google.com/g/2005#home'>
12
+ (206)555-1213
13
+ </gd:phoneNumber>
14
+ <gd:phoneNumber rel='http://schemas.google.com/g/2005#mobile'>
15
+ (206) 555-1212
16
+ </gd:phoneNumber>
17
+ <gd:im rel='http://schemas.google.com/g/2005#home'
18
+ protocol='http://schemas.google.com/g/2005#GOOGLE_TALK'
19
+ address='liz@gmail.com'/>
20
+ <gd:postalAddress rel='http://schemas.google.com/g/2005#work' primary='true'>
21
+ 1600 Amphitheatre Pkwy
22
+ Mountain View, CA 94043
23
+ </gd:postalAddress>
24
+ <gd:postalAddress rel='http://schemas.google.com/g/2005#home'>
25
+ 800 Main Street
26
+ Mountain View, CA 94041
27
+ </gd:postalAddress>
28
+ <gd:organization>
29
+ <gd:orgName>Google, Inc.</gd:orgName>
30
+ <gd:orgTitle>Tech Writer</gd:orgTitle>
31
+ </gd:organization>
32
+ </entry>
33
+
34
+ <entry>
35
+ <title>Poor Jack</title>
36
+ <content>Poor Jack doesn't have an e-mail address</content>
37
+ </entry>
38
+
39
+ <entry>
40
+ <title>William Paginate</title>
41
+ <gd:email address='will_paginate@googlegroups.com' />
42
+ </entry>
43
+
44
+ <entry>
45
+ <content>This guy doesn't have a name</content>
46
+ <gd:email address='anonymous@example.com' />
47
+ </entry>
48
+ </feed>
@@ -0,0 +1,46 @@
1
+ <!-- source: http://code.google.com/apis/contacts/developers_guide_protocol.html -->
2
+ <feed xmlns='http://www.w3.org/2005/Atom'
3
+ xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'
4
+ xmlns:gd='http://schemas.google.com/g/2005'>
5
+ <id>http://www.google.com/m8/feeds/contacts/liz%40gmail.com/base</id>
6
+ <updated>2008-03-05T12:36:38.836Z</updated>
7
+ <category scheme='http://schemas.google.com/g/2005#kind'
8
+ term='http://schemas.google.com/contact/2008#contact' />
9
+ <title type='text'>Contacts</title>
10
+ <link rel='http://schemas.google.com/g/2005#feed'
11
+ type='application/atom+xml'
12
+ href='http://www.google.com/m8/feeds/contacts/liz%40gmail.com/base' />
13
+ <link rel='http://schemas.google.com/g/2005#post'
14
+ type='application/atom+xml'
15
+ href='http://www.google.com/m8/feeds/contacts/liz%40gmail.com/base' />
16
+ <link rel='self' type='application/atom+xml'
17
+ href='http://www.google.com/m8/feeds/contacts/liz%40gmail.com/base?max-results=25' />
18
+ <author>
19
+ <name>Elizabeth Bennet</name>
20
+ <email>liz@gmail.com</email>
21
+ </author>
22
+ <generator version='1.0' uri='http://www.google.com/m8/feeds/contacts'>
23
+ Contacts
24
+ </generator>
25
+ <openSearch:totalResults>1</openSearch:totalResults>
26
+ <openSearch:startIndex>1</openSearch:startIndex>
27
+ <openSearch:itemsPerPage>25</openSearch:itemsPerPage>
28
+ <entry>
29
+ <id>
30
+ http://www.google.com/m8/feeds/contacts/liz%40gmail.com/base/c9012de
31
+ </id>
32
+ <updated>2008-03-05T12:36:38.835Z</updated>
33
+ <category scheme='http://schemas.google.com/g/2005#kind'
34
+ term='http://schemas.google.com/contact/2008#contact' />
35
+ <title type='text'>Fitzgerald</title>
36
+ <link rel='self' type='application/atom+xml'
37
+ href='http://www.google.com/m8/feeds/contacts/liz%40gmail.com/base/c9012de' />
38
+ <link rel='edit' type='application/atom+xml'
39
+ href='http://www.google.com/m8/feeds/contacts/liz%40gmail.com/base/c9012de/1204720598835000' />
40
+ <gd:phoneNumber rel='http://schemas.google.com/g/2005#home'
41
+ primary='true'>
42
+ 456
43
+ </gd:phoneNumber>
44
+ <gd:email label="Personal" rel="http://schemas.google.com/g/2005#home" address="fubar@gmail.com" primary="true" />
45
+ </entry>
46
+ </feed>