ews-api 0.1.0.a → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -8,11 +8,11 @@ begin
8
8
  gem.summary = 'Exchange Web Services API'
9
9
  gem.description = "Exchange Web Services API. It doesn't use soap4r."
10
10
  gem.email = "jeremy.burks@gmail.com"
11
- gem.homepage = "http://github.com/jrun/ews-api"
11
+ gem.homepage = "http://jrun.github.com/ews-api/ews"
12
12
  gem.authors = ["jrun"]
13
13
  gem.add_dependency 'httpclient'
14
14
  gem.add_dependency 'rubyntlm'
15
- gem.add_dependency 'handsoap', '1.1.4'
15
+ gem.add_dependency 'handsoap', '1.1.6'
16
16
  gem.add_development_dependency "rspec", ">= 1.2.9"
17
17
  gem.add_development_dependency "yard", ">= 0"
18
18
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0.a
1
+ 0.1.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{ews-api}
8
- s.version = "0.1.0.a"
8
+ s.version = "0.1.0"
9
9
 
10
- s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["jrun"]
12
- s.date = %q{2009-12-17}
12
+ s.date = %q{2010-01-25}
13
13
  s.description = %q{Exchange Web Services API. It doesn't use soap4r.}
14
14
  s.email = %q{jeremy.burks@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -26,6 +26,10 @@ Gem::Specification.new do |s|
26
26
  "ews-api.gemspec",
27
27
  "lib/ews-api.rb",
28
28
  "lib/ews/attachment.rb",
29
+ "lib/ews/builder.rb",
30
+ "lib/ews/builders/resolve_names_builder.rb",
31
+ "lib/ews/builders/shape_builder.rb",
32
+ "lib/ews/distinguished_folders.rb",
29
33
  "lib/ews/error.rb",
30
34
  "lib/ews/folder.rb",
31
35
  "lib/ews/message.rb",
@@ -33,6 +37,9 @@ Gem::Specification.new do |s|
33
37
  "lib/ews/parser.rb",
34
38
  "lib/ews/service.rb",
35
39
  "spec/ews/attachment_spec.rb",
40
+ "spec/ews/builder_spec.rb",
41
+ "spec/ews/builders/resolve_names_builder_spec.rb",
42
+ "spec/ews/builders/shape_builder_spec.rb",
36
43
  "spec/ews/folder_spec.rb",
37
44
  "spec/ews/message_spec.rb",
38
45
  "spec/ews/model_spec.rb",
@@ -52,7 +59,7 @@ Gem::Specification.new do |s|
52
59
  "spec/spec.opts",
53
60
  "spec/spec_helper.rb"
54
61
  ]
55
- s.homepage = %q{http://github.com/jrun/ews-api}
62
+ s.homepage = %q{http://jrun.github.com/ews-api/ews}
56
63
  s.rdoc_options = ["--charset=UTF-8"]
57
64
  s.require_paths = ["lib"]
58
65
  s.rubygems_version = %q{1.3.5}
@@ -62,9 +69,12 @@ Gem::Specification.new do |s|
62
69
  "spec/integration.rb",
63
70
  "spec/ews/parser_spec.rb",
64
71
  "spec/ews/message_spec.rb",
72
+ "spec/ews/builder_spec.rb",
65
73
  "spec/ews/attachment_spec.rb",
66
74
  "spec/ews/folder_spec.rb",
67
75
  "spec/ews/service_spec.rb",
76
+ "spec/ews/builders/resolve_names_builder_spec.rb",
77
+ "spec/ews/builders/shape_builder_spec.rb",
68
78
  "spec/ews/model_spec.rb"
69
79
  ]
70
80
 
@@ -75,20 +85,20 @@ Gem::Specification.new do |s|
75
85
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
76
86
  s.add_runtime_dependency(%q<httpclient>, [">= 0"])
77
87
  s.add_runtime_dependency(%q<rubyntlm>, [">= 0"])
78
- s.add_runtime_dependency(%q<handsoap>, ["= 1.1.4"])
88
+ s.add_runtime_dependency(%q<handsoap>, ["= 1.1.6"])
79
89
  s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
80
90
  s.add_development_dependency(%q<yard>, [">= 0"])
81
91
  else
82
92
  s.add_dependency(%q<httpclient>, [">= 0"])
83
93
  s.add_dependency(%q<rubyntlm>, [">= 0"])
84
- s.add_dependency(%q<handsoap>, ["= 1.1.4"])
94
+ s.add_dependency(%q<handsoap>, ["= 1.1.6"])
85
95
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
86
96
  s.add_dependency(%q<yard>, [">= 0"])
87
97
  end
88
98
  else
89
99
  s.add_dependency(%q<httpclient>, [">= 0"])
90
100
  s.add_dependency(%q<rubyntlm>, [">= 0"])
91
- s.add_dependency(%q<handsoap>, ["= 1.1.4"])
101
+ s.add_dependency(%q<handsoap>, ["= 1.1.6"])
92
102
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
93
103
  s.add_dependency(%q<yard>, [">= 0"])
94
104
  end
@@ -2,10 +2,14 @@ require 'net/ntlm'
2
2
  require 'handsoap'
3
3
 
4
4
  require 'ews/error'
5
+ require "ews/distinguished_folders"
5
6
  require 'ews/model'
6
7
  require 'ews/attachment'
7
8
  require 'ews/message'
8
9
  require 'ews/folder'
10
+ require "ews/builders/shape_builder"
11
+ require "ews/builders/resolve_names_builder"
12
+ require 'ews/builder'
9
13
  require 'ews/parser'
10
14
  require 'ews/service'
11
15
 
@@ -0,0 +1,107 @@
1
+ require 'forwardable'
2
+
3
+ module EWS
4
+
5
+ # AdditionalProperties
6
+ # @see http://msdn.microsoft.com/en-us/library/aa580545(EXCHG.80).aspx
7
+ # BaseShape
8
+ # @see http://msdn.microsoft.com/en-us/library/aa565622(EXCHG.80).aspx
9
+ # BodyType
10
+ # @see http://msdn.microsoft.com/en-us/library/aa580499(EXCHG.80).aspx
11
+ # IncludeMimeContent
12
+ class Builder
13
+ extend Forwardable
14
+
15
+ def_delegators :@resolve_names_builder,
16
+ :unresolved_entry!,
17
+ :return_full_contact_data!
18
+
19
+ def_delegators :@shape_builder,
20
+ :item_shape!,
21
+ :folder_shape!,
22
+ :attachment_shape!
23
+
24
+ def initialize(action_node, opts, &block)
25
+ @action_node, @opts = action_node, opts
26
+ @resolve_names_builder = ResolveNamesBuilder.new(action_node)
27
+ @shape_builder = ShapeBuilder.new(action_node, opts)
28
+ instance_eval(&block) if block_given?
29
+ end
30
+
31
+ def item_id_container!(container_node_name, item_ids)
32
+ id_container!(container_node_name, item_ids) do |container_node, id|
33
+ item_id! container_node, id, @opts
34
+ end
35
+ end
36
+
37
+ def folder_id_container!(container_node_name, folder_ids)
38
+ id_container!(container_node_name, folder_ids) do |container_node, id|
39
+ folder_id! container_node, id, @opts
40
+ end
41
+ end
42
+
43
+ def attachment_ids!(attachment_ids)
44
+ id_container!('tns:AttachmentIds', attachment_ids) do |container_node, id|
45
+ id_node! container_node, 't:AttachmentId', id
46
+ end
47
+ end
48
+
49
+ def id_container!(container_node_name, ids)
50
+ @action_node.add(container_node_name) do |container_node|
51
+ to_a(ids).each {|id| yield container_node, id }
52
+ end
53
+ end
54
+
55
+ def traversal!
56
+ @action_node.set_attr 'Traversal', (@opts[:traversal] || :Shallow)
57
+ end
58
+
59
+ # @see http://msdn.microsoft.com/en-us/library/aa580234(EXCHG.80).aspx
60
+ # ItemId
61
+ def item_id!(container_node, item_id, opts = {})
62
+ id_node! container_node, 't:ItemId', item_id, opts
63
+ end
64
+
65
+ # @param parent [Handsoap::XmlMason::Node]
66
+ #
67
+ # @param folder_id [String, Symbol] When a EWS::DistinguishedFolder a
68
+ # DistinguishedFolderId is created otherwise FolderId is used
69
+ #
70
+ # @param [Hash] opts
71
+ # @option opts [Symbol] :change_key
72
+ #
73
+ # @see http://msdn.microsoft.com/en-us/library/aa580808(EXCHG.80).aspx
74
+ # DistinguishedFolderId
75
+ #
76
+ # @see http://msdn.microsoft.com/en-us/library/aa579461(EXCHG.80).aspx
77
+ # FolderId
78
+ def folder_id!(container_node, folder_id, opts = {})
79
+ node_name = if DistinguishedFolders.include?(folder_id)
80
+ 't:DistinguishedFolderId'
81
+ else
82
+ 't:FolderId'
83
+ end
84
+ id_node! container_node, node_name, folder_id, opts
85
+ end
86
+
87
+ # @param opts [Hash] Still an argument so opts can remain optional
88
+ def id_node!(container_node, id_node_name, id, opts = {})
89
+ container_node.add(id_node_name) do |id_node|
90
+ id_node.set_attr 'Id', id
91
+ id_node.set_attr 'ChangeKey', opts[:change_key] if opts[:change_key]
92
+ end
93
+ end
94
+
95
+ # TODO: core_ext?
96
+ def to_a(ids)
97
+ case ids
98
+ when Enumerable
99
+ ids
100
+ else
101
+ [ids]
102
+ end
103
+ end
104
+
105
+ end
106
+
107
+ end
@@ -0,0 +1,15 @@
1
+ module EWS
2
+ class ResolveNamesBuilder
3
+ def initialize(action_node)
4
+ @action_node = action_node
5
+ end
6
+
7
+ def unresolved_entry!(entry)
8
+ @action_node.add('tns:UnresolvedEntry', entry)
9
+ end
10
+
11
+ def return_full_contact_data!(return_full_contact_data)
12
+ @action_node.set_attr 'ReturnFullContactData', return_full_contact_data
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,71 @@
1
+ module EWS
2
+ class ShapeBuilder
3
+ def initialize(action_node, opts = {})
4
+ @action_node, @opts = action_node, opts
5
+ @shape_node = nil
6
+ end
7
+
8
+ # @param [Hash] opts
9
+ # @option opts [String, Symbol] :base_shape (Default) IdOnly, Default, AllProperties
10
+ # @option opts [true, false] :include_mime_content
11
+ # @option opts [String, Symbol] :body_type Best, HTML or Text
12
+ # @option opts [Symbol] :additional_properties
13
+ def item_shape!
14
+ set_shape_node 'tns:ItemShape'
15
+ base_shape!
16
+ include_mime_content!
17
+ body_type!
18
+ additional_properties!
19
+ end
20
+
21
+ # @param [Hash] opts
22
+ # @option opts [String, Symbol] :base_shape (Default) IdOnly, Default, AllProperties
23
+ # @option opts [Symbol] :additional_properties
24
+ def folder_shape!
25
+ set_shape_node 'tns:FolderShape'
26
+ base_shape!
27
+ additional_properties!
28
+ end
29
+
30
+ # @param [Hash] opts
31
+ # @option opts [true, false] :include_mime_type
32
+ # @option opts [String, Symbol] :body_type Best, HTML or Text
33
+ # @option opts [Symbol] :additional_properties
34
+ #
35
+ # @see http://msdn.microsoft.com/en-us/library/aa563727(EXCHG.80).aspx
36
+ # AttachmentShape
37
+ def attachment_shape!
38
+ set_shape_node 'tns:AttachmentShape'
39
+ include_mime_content!
40
+ body_type!
41
+ additional_properties!
42
+ end
43
+
44
+ private
45
+ def set_shape_node(name)
46
+ @action_node.add(name) do |shape_node|
47
+ @shape_node = shape_node
48
+ end
49
+ end
50
+
51
+ def base_shape!
52
+ @opts[:base_shape] ||= :Default
53
+ @shape_node.add 't:BaseShape', @opts[:base_shape]
54
+ end
55
+
56
+ def include_mime_content!
57
+ if @opts.has_key?(:include_mime_content)
58
+ @shape_node.add 't:IncludeMimeContent', @opts[:include_mime_content]
59
+ end
60
+ end
61
+
62
+ def body_type!
63
+ if @opts.has_key?(:body_type)
64
+ @shape_node.add 't:BodyType', @opts[:body_type]
65
+ end
66
+ end
67
+
68
+ def additional_properties!
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,17 @@
1
+ module EWS
2
+ DistinguishedFolders = [:calendar,
3
+ :contacts,
4
+ :deleteditems,
5
+ :drafts,
6
+ :inbox,
7
+ :journal,
8
+ :notes,
9
+ :outbox,
10
+ :sentitems,
11
+ :tasks,
12
+ :msgfolderroot,
13
+ :root,
14
+ :junkemail,
15
+ :searchfolders,
16
+ :voicemail ].freeze
17
+ end
@@ -1,6 +1,10 @@
1
1
  module EWS
2
2
 
3
3
  class Parser
4
+ def parse_resolve_names(doc)
5
+ raise 'TODO'
6
+ end
7
+
4
8
  def parse_find_folder(doc)
5
9
  doc.xpath('//t:Folders/child::*').map do |node|
6
10
  parse_exchange_folder node.xpath('.') # force NodeSelection
@@ -27,16 +27,19 @@ module EWS
27
27
  end
28
28
 
29
29
  def on_create_document(doc)
30
- # register namespaces for the request
31
- doc.alias 'tns', 'http://schemas.microsoft.com/exchange/services/2006/messages'
32
- doc.alias 't', 'http://schemas.microsoft.com/exchange/services/2006/types'
30
+ register_aliases! doc
33
31
  end
34
32
 
35
33
  def on_response_document(doc)
36
34
  apply_namespaces! doc
37
35
  parser.parse_response_message doc
38
36
  end
39
-
37
+
38
+ def register_aliases!(doc)
39
+ doc.alias 'tns', 'http://schemas.microsoft.com/exchange/services/2006/messages'
40
+ doc.alias 't', 'http://schemas.microsoft.com/exchange/services/2006/types'
41
+ end
42
+
40
43
  def apply_namespaces!(doc)
41
44
  doc.add_namespace 'soap', '"http://schemas.xmlsoap.org/soap/envelope'
42
45
  doc.add_namespace 't', 'http://schemas.microsoft.com/exchange/services/2006/types'
@@ -44,11 +47,15 @@ module EWS
44
47
  end
45
48
  # public methods
46
49
 
47
- def resolve_names!
50
+ def resolve_names!(unresolved_entry, return_full_contact_data = true)
48
51
  soap_action = 'http://schemas.microsoft.com/exchange/services/2006/messages/ResolveNames'
49
- response = invoke('tns:ResolveNames', soap_action) do |message|
50
- raise "TODO"
52
+ response = invoke('tns:ResolveNames', soap_action) do |resolve_names|
53
+ builder(resolve_names) do
54
+ unresolved_entry! unresolved_entry
55
+ return_full_contact_data! return_full_contact_data
56
+ end
51
57
  end
58
+ parser.parse_resolve_names response.document
52
59
  end
53
60
 
54
61
  def expand_dl!
@@ -82,20 +89,14 @@ module EWS
82
89
  # @todo Support options
83
90
  # Traversal: +Shallow, Deep, SoftDeleted+
84
91
  # FolderShape: +IdOnly, Default, AllProperties+
85
- def find_folder(parent_folder_name = :root, opts = {})
86
- soap_action = 'http://schemas.microsoft.com/exchange/services/2006/messages/FindFolder'
87
- opts[:base_shape] ||= :Default
88
-
92
+ def find_folder(folder_ids = :root, opts = {})
93
+ soap_action = 'http://schemas.microsoft.com/exchange/services/2006/messages/FindFolder'
89
94
  response = invoke('tns:FindFolder', soap_action) do |find_folder|
90
- find_folder.set_attr 'Traversal', 'Deep'
91
- find_folder.add('tns:FolderShape') do |shape|
92
- shape.add 't:BaseShape', opts[:base_shape]
93
- end
94
- find_folder.add('tns:ParentFolderIds') do |ids|
95
- ids.add('t:DistinguishedFolderId') do |id|
96
- id.set_attr 'Id', parent_folder_name.to_s.downcase
97
- end
98
- end
95
+ builder(find_folder, opts) do
96
+ traversal!
97
+ folder_shape!
98
+ folder_id_container! 'tns:ParentFolderIds', folder_ids
99
+ end
99
100
  end
100
101
  parser.parse_find_folder response.document
101
102
  end
@@ -118,16 +119,12 @@ module EWS
118
119
  # @see http://msdn.microsoft.com/en-us/library/aa580274.aspx
119
120
  # MSDN - GetFolder operation
120
121
  #
121
- def get_folder(name = :root, opts = {})
122
- soap_action = 'http://schemas.microsoft.com/exchange/services/2006/messages/GetFolder'
123
- opts[:base_shape] ||= :Default
124
-
122
+ def get_folder(folder_id = :root, opts = {})
123
+ soap_action = 'http://schemas.microsoft.com/exchange/services/2006/messages/GetFolder'
125
124
  response = invoke('tns:GetFolder', soap_action) do |get_folder|
126
- get_folder.add('tns:FolderShape') do |shape|
127
- shape.add 't:BaseShape', opts[:base_shape]
128
- end
129
- get_folder.add('tns:FolderIds') do |ids|
130
- ids.add('t:DistinguishedFolderId') { |id| id.set_attr 'Id', name }
125
+ builder(get_folder, opts) do
126
+ folder_shape!
127
+ folder_id_container! 'tns:FolderIds', folder_id
131
128
  end
132
129
  end
133
130
  parser.parse_get_folder response.document
@@ -241,19 +238,13 @@ module EWS
241
238
  #
242
239
  # @see http://msdn.microsoft.com/en-us/library/aa580545.aspx
243
240
  # BaseShape
244
- def find_item(parent_folder_name = :root, opts = {})
245
- soap_action = 'http://schemas.microsoft.com/exchange/services/2006/messages/FindItem'
246
- opts[:base_shape] ||= :IdOnly
247
-
241
+ def find_item(folder_ids = :root, opts = {})
242
+ soap_action = 'http://schemas.microsoft.com/exchange/services/2006/messages/FindItem'
248
243
  response = invoke('tns:FindItem', soap_action) do |find_item|
249
- find_item.set_attr 'Traversal', 'Shallow'
250
- find_item.add('tns:ItemShape') do |shape|
251
- shape.add 't:BaseShape', opts[:base_shape]
252
- end
253
- find_item.add('tns:ParentFolderIds') do |ids|
254
- ids.add('t:DistinguishedFolderId') do |folder_id|
255
- folder_id.set_attr 'Id', parent_folder_name.to_s.downcase
256
- end
244
+ builder(find_item, opts) do
245
+ traversal!
246
+ item_shape!
247
+ folder_id_container! 'tns:ParentFolderIds', folder_ids
257
248
  end
258
249
  end
259
250
  parser.parse_find_item response.document
@@ -285,29 +276,22 @@ module EWS
285
276
  # ItmeIds
286
277
  def get_item(item_id, opts = {})
287
278
  soap_action = 'http://schemas.microsoft.com/exchange/services/2006/messages/GetItem'
288
- opts[:base_shape] ||= :Default
289
-
290
279
  response = invoke('tns:GetItem', soap_action) do |get_item|
291
- get_item.add('tns:ItemShape') do |shape|
292
- shape.add 't:BaseShape', opts[:base_shape]
293
- shape.add 't:IncludeMimeContent', false
294
- end
295
- get_item.add('tns:ItemIds') do |ids|
296
- ids.add('t:ItemId') do |item|
297
- item.set_attr 'Id', item_id
298
- if opts[:change_key]
299
- item.set_attr 'ChangeKey', opts[:change_key]
300
- end
301
- end
280
+ builder(get_item, opts) do
281
+ item_shape!
282
+ item_id_container! 'tns:ItemIds', item_id
302
283
  end
303
284
  end
304
285
  parser.parse_get_item response.document
305
286
  end
306
287
 
307
- def create_item!
288
+ def create_item!(item, destination_folder_id, opts = {})
308
289
  soap_action = 'http://schemas.microsoft.com/exchange/services/2006/messages/CreateItem'
309
- response = invoke('tns:CreateItem', soap_action) do |message|
310
- raise "TODO"
290
+ response = invoke('tns:CreateItem', soap_action) do |create_item|
291
+ builder(create_item, opts) do
292
+ folder_id_container! 'SavedItemFolderId', destination_folder_id
293
+ end
294
+ raise 'TODO'
311
295
  end
312
296
  end
313
297
 
@@ -352,20 +336,12 @@ module EWS
352
336
  # @see http://msdn.microsoft.com/en-us/library/aa580808%28EXCHG.80%29.aspx
353
337
  # DistinguishedFolderId
354
338
  #
355
- def move_item!(folder_id, item_ids)
339
+ def move_item!(folder_id, item_id, opts = {})
356
340
  soap_action = 'http://schemas.microsoft.com/exchange/services/2006/messages/MoveItem'
357
341
  response = invoke('tns:MoveItem', soap_action) do |move_item|
358
- move_item.add('tns:ToFolderId') do |to_folder|
359
-
360
- # TODO: Support both FolderID and DistinguishedFolderId
361
- to_folder.add('t:FolderId') do |folder_id_node|
362
- folder_id_node.set_attr 'Id', folder_id
363
- end
364
- end
365
- move_item.add('tns:ItemIds') do |ids|
366
- item_ids.each do |item_id|
367
- ids.add('t:ItemId') {|item_node| item_node.set_attr 'Id', item_id }
368
- end
342
+ builder(move_item, opts) do
343
+ folder_id_container! 'tns:ToFolderId', folder_id
344
+ item_id_container! 'tns:ItemIds', item_id
369
345
  end
370
346
  end
371
347
  end
@@ -402,14 +378,12 @@ module EWS
402
378
  #
403
379
  # @see http://msdn.microsoft.com/en-us/library/aa494316.aspx
404
380
  # GetAttachment
405
- def get_attachment(attachment_id)
381
+ def get_attachment(attachment_id, opts = {})
406
382
  soap_action = 'http://schemas.microsoft.com/exchange/services/2006/messages/GetAttachment'
407
383
  response = invoke('tns:GetAttachment', soap_action) do |get_attachment|
408
- get_attachment.add('tns:AttachmentShape')
409
- get_attachment.add('tns:AttachmentIds') do |ids|
410
- ids.add('t:AttachmentId') do |attachment|
411
- attachment.set_attr 'Id', attachment_id
412
- end
384
+ builder(get_attachment, opts) do
385
+ attachment_shape!
386
+ attachment_ids! attachment_id
413
387
  end
414
388
  end
415
389
  parser.parse_get_attachment response.document
@@ -468,9 +442,9 @@ module EWS
468
442
  def parser
469
443
  @parser ||= Parser.new
470
444
  end
471
-
472
- # helpers
473
-
474
- # TODO
445
+
446
+ def builder(action_node, opts = {}, &block)
447
+ Builder.new(action_node, opts, &block)
448
+ end
475
449
  end
476
450
  end
@@ -0,0 +1,125 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+
3
+ module BuilderHelper
4
+ def builder(opts = {})
5
+ EWS::Builder.new(@doc, opts)
6
+ end
7
+ end
8
+
9
+ describe EWS::Builder do
10
+ include BuilderHelper
11
+
12
+ before(:each) do
13
+ @doc = new_document
14
+ end
15
+
16
+ context '#item_id! should build ItemId' do
17
+ def expected_item_id
18
+ %Q|<t:ItemId #{TNS} Id="XYZ" />|
19
+ end
20
+
21
+ def expected_item_id_with_change_key
22
+ %Q|<t:ItemId #{TNS} ChangeKey="123" Id="XYZ" />|
23
+ end
24
+
25
+ it "given an id" do
26
+ builder.item_id!(@doc, 'XYZ')
27
+ @doc.to_s.should == expected_item_id
28
+ end
29
+
30
+ it "with a ChangeKey whe the :change_key option is given" do
31
+ builder.item_id!(@doc, 'XYZ', :change_key => '123')
32
+ @doc.to_s.should == expected_item_id_with_change_key
33
+ end
34
+ end
35
+
36
+ context '#folder_id!' do
37
+ context 'should build FolderId' do
38
+ def expected_folder_id
39
+ %Q|<t:FolderId #{TNS} Id="XYZ" />|
40
+ end
41
+
42
+ def expected_folder_id_with_change_key
43
+ %Q|<t:FolderId #{TNS} ChangeKey="123" Id="XYZ" />|
44
+ end
45
+
46
+ it "given an id" do
47
+ builder.folder_id!(@doc, 'XYZ')
48
+ @doc.to_s.should == expected_folder_id
49
+ end
50
+
51
+ it "with a ChangeKey whe the :change_key option is given" do
52
+ builder.folder_id!(@doc, 'XYZ', :change_key => '123')
53
+ @doc.to_s.should == expected_folder_id_with_change_key
54
+ end
55
+ end
56
+
57
+ context "should build a DistinguishedFolderId" do
58
+ def expected_distinguished_folder_id(id)
59
+ %Q|<t:DistinguishedFolderId #{TNS} Id="#{id}" />|
60
+ end
61
+
62
+ def expected_distinguished_folder_id_with_change_key
63
+ %Q|<t:DistinguishedFolderId #{TNS} ChangeKey="222" Id="inbox" />|
64
+ end
65
+
66
+ EWS::DistinguishedFolders.each do |folder|
67
+ it "given #{folder.inspect}" do
68
+ builder.folder_id!(@doc, folder)
69
+ @doc.to_s.should == expected_distinguished_folder_id(folder)
70
+ end
71
+ end
72
+
73
+ it "with a ChangeKey when given the :change_key option" do
74
+ builder.folder_id!(@doc, :inbox, :change_key => '222')
75
+ @doc.to_s.should == expected_distinguished_folder_id_with_change_key
76
+ end
77
+ end
78
+ end
79
+
80
+ context "#folder_id_container should bulid the container node" do
81
+ def expected_parent_folder_ids_with_one
82
+ (<<-EOS
83
+ <tns:ParentFolderIds #{MNS}>
84
+ <t:FolderId #{TNS} Id="111" />
85
+ </tns:ParentFolderIds>
86
+ EOS
87
+ ).chomp
88
+ end
89
+
90
+ def expected_parent_folder_ids_with_one_distinguished
91
+ (<<-EOS
92
+ <tns:ParentFolderIds #{MNS}>
93
+ <t:DistinguishedFolderId #{TNS} Id="inbox" />
94
+ </tns:ParentFolderIds>
95
+ EOS
96
+ ).chomp
97
+ end
98
+
99
+ def expected_parent_folder_ids_with_more
100
+ (<<-EOS
101
+ <tns:ParentFolderIds #{MNS}>
102
+ <t:FolderId #{TNS} Id="111" />
103
+ <t:DistinguishedFolderId #{TNS} Id="inbox" />
104
+ </tns:ParentFolderIds>
105
+ EOS
106
+ ).chomp
107
+ end
108
+
109
+ it "when given one id" do
110
+ builder.folder_id_container! 'tns:ParentFolderIds', '111'
111
+ @doc.to_s.should == expected_parent_folder_ids_with_one
112
+ end
113
+
114
+ it "when given one distinguished folder" do
115
+ builder.folder_id_container! 'tns:ParentFolderIds', :inbox
116
+ @doc.to_s.should == expected_parent_folder_ids_with_one_distinguished
117
+ end
118
+
119
+ it "when given an array of ids" do
120
+ builder.folder_id_container! 'tns:ParentFolderIds', ['111', :inbox]
121
+ @doc.to_s.should == expected_parent_folder_ids_with_more
122
+ end
123
+ end
124
+
125
+ end
@@ -0,0 +1,42 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
2
+
3
+ module EWS
4
+ describe ResolveNamesBuilder do
5
+ before(:each) do
6
+ @action_node = Handsoap::XmlMason::Element.new(new_document, 'tns', 'ResolveNames')
7
+ @builder = ResolveNamesBuilder.new(@action_node)
8
+ end
9
+
10
+ context "#unresolved_entry!" do
11
+ def expected_unresolved_entry_xml
12
+ (<<-EOS
13
+ <tns:ResolveNames #{MNS}>
14
+ <tns:UnresolvedEntry>Stark</tns:UnresolvedEntry>
15
+ </tns:ResolveNames>
16
+ EOS
17
+ ).chomp
18
+ end
19
+
20
+ it "should build a UnresolvedEntry node" do
21
+ @builder.unresolved_entry!('Stark')
22
+ @action_node.to_s.should == expected_unresolved_entry_xml
23
+ end
24
+ end
25
+
26
+ context "#return_full_contact_data!" do
27
+ it "should add attribute when true" do
28
+ @builder.return_full_contact_data!(true)
29
+
30
+ expected_xml = %Q|<tns:ResolveNames ReturnFullContactData="true" #{MNS} />|
31
+ @action_node.to_s.should == expected_xml
32
+ end
33
+
34
+ it "should add attribute when false" do
35
+ @builder.return_full_contact_data!(false)
36
+
37
+ expected_xml = %Q|<tns:ResolveNames ReturnFullContactData="false" #{MNS} />|
38
+ @action_node.to_s.should == expected_xml
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,140 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
2
+
3
+ module EWS
4
+ describe ShapeBuilder do
5
+ before(:each) do
6
+ @doc = new_document
7
+ end
8
+
9
+ def builder(opts = {})
10
+ ShapeBuilder.new(@doc, opts)
11
+ end
12
+
13
+ context "#item_shape! should build an ItemShape node" do
14
+ def expected_item_shape(base_shape)
15
+ ( <<-EOS
16
+ <tns:ItemShape #{MNS}>
17
+ <t:BaseShape #{TNS}>#{base_shape}</t:BaseShape>
18
+ </tns:ItemShape>
19
+ EOS
20
+ ).chomp
21
+ end
22
+
23
+ def expected_include_mime_type(include_mime_type)
24
+ ( <<-EOS
25
+ <tns:ItemShape #{MNS}>
26
+ <t:BaseShape #{TNS}>Default</t:BaseShape>
27
+ <t:IncludeMimeContent #{TNS}>#{include_mime_type}</t:IncludeMimeContent>
28
+ </tns:ItemShape>
29
+ EOS
30
+ ).chomp
31
+ end
32
+
33
+ it "with the BaseShape of 'Default' when no :base_shape option is given" do
34
+ builder.item_shape!
35
+ @doc.to_s.should == expected_item_shape('Default')
36
+ end
37
+
38
+ it "with the BaseShape of 'Default'" do
39
+ builder.item_shape!
40
+ @doc.to_s.should == expected_item_shape('Default')
41
+ end
42
+
43
+ it "with the BaseShape of 'AllProperties'" do
44
+ builder(:base_shape => 'AllProperties').item_shape!
45
+ @doc.to_s.should == expected_item_shape('AllProperties')
46
+ end
47
+
48
+ it "with the BaseShape of 'IdOnly'" do
49
+ builder(:base_shape => 'IdOnly').item_shape!
50
+ @doc.to_s.should == expected_item_shape('IdOnly')
51
+ end
52
+
53
+ it "with IncludeMimeContent false" do
54
+ builder(:include_mime_content => false).item_shape!
55
+ @doc.to_s.should == expected_include_mime_type(false)
56
+ end
57
+
58
+ it "with IncludeMimeContent true" do
59
+ builder(:include_mime_content => true).item_shape!
60
+ @doc.to_s.should == expected_include_mime_type(true)
61
+ end
62
+ end
63
+
64
+ context "#folder_shape! should build an FolderShape node" do
65
+ def expected_folder_shape(base_shape)
66
+ ( <<-EOS
67
+ <tns:FolderShape #{MNS}>
68
+ <t:BaseShape #{TNS}>#{base_shape}</t:BaseShape>
69
+ </tns:FolderShape>
70
+ EOS
71
+ ).chomp
72
+ end
73
+
74
+ it "with the BaseShape of 'Default' when no :base_shape option is given" do
75
+ builder.folder_shape!
76
+ @doc.to_s.should == expected_folder_shape('Default')
77
+ end
78
+
79
+ it "with the BaseShape of 'Default'" do
80
+ builder.folder_shape!
81
+ @doc.to_s.should == expected_folder_shape('Default')
82
+ end
83
+
84
+ it "with the BaseShape of 'AllProperties'" do
85
+ builder(:base_shape => 'AllProperties').folder_shape!
86
+ @doc.to_s.should == expected_folder_shape('AllProperties')
87
+ end
88
+
89
+ it "with the BaseShape of 'IdOnly'" do
90
+ builder(:base_shape => 'IdOnly').folder_shape!
91
+ @doc.to_s.should == expected_folder_shape('IdOnly')
92
+ end
93
+ end
94
+
95
+ context "#attachment_shape! should build an AttachmentShape node" do
96
+ def expected_empty_shape
97
+ "<tns:AttachmentShape #{MNS} />"
98
+ end
99
+
100
+ def expected_include_mime_type(include_mime_type)
101
+ ( <<-EOS
102
+ <tns:AttachmentShape #{MNS}>
103
+ <t:IncludeMimeContent #{TNS}>#{include_mime_type}</t:IncludeMimeContent>
104
+ </tns:AttachmentShape>
105
+ EOS
106
+ ).chomp
107
+ end
108
+
109
+ def expected_body_type(body_type)
110
+ ( <<-EOS
111
+ <tns:AttachmentShape #{MNS}>
112
+ <t:BodyType #{TNS}>#{body_type}</t:BodyType>
113
+ </tns:AttachmentShape>
114
+ EOS
115
+ ).chomp
116
+ end
117
+
118
+ it "an empty shape when no options are given" do
119
+ builder.attachment_shape!
120
+ @doc.to_s.should == expected_empty_shape
121
+ end
122
+
123
+ it "with IncludeMimeContent false" do
124
+ builder(:include_mime_content => false).attachment_shape!
125
+ @doc.to_s.should == expected_include_mime_type(false)
126
+ end
127
+
128
+ it "with IncludeMimeContent true" do
129
+ builder(:include_mime_content => true).attachment_shape!
130
+ @doc.to_s.should == expected_include_mime_type(true)
131
+ end
132
+
133
+ it "with BodyType Best" do
134
+ builder(:body_type => :Best).attachment_shape!
135
+ @doc.to_s.should == expected_body_type(:Best)
136
+ end
137
+ end
138
+
139
+ end
140
+ end
@@ -35,6 +35,14 @@ end
35
35
  EWS::Service.logger = $stdout
36
36
 
37
37
  describe 'Integration Tests' do
38
+ context "resolve_names" do
39
+ it "should resolve names" do
40
+ lambda do
41
+ EWS::Service.resolve_names! EWS_CONFIG['resolve_names']
42
+ end.should_not raise_error
43
+ end
44
+ end
45
+
38
46
  context 'find_folder' do
39
47
  it "should find the folder without errors" do
40
48
  lambda do
@@ -42,11 +50,10 @@ describe 'Integration Tests' do
42
50
  end.should_not raise_error
43
51
  end
44
52
 
45
- it "should raise a Fault when the item does not exist" do
46
- error_msg = /The value 'does-not-exist' is invalid according to its datatype/
53
+ it "should raise a ResponseError when the folder does not exist" do
47
54
  lambda do
48
55
  EWS::Service.find_folder('does-not-exist')
49
- end.should raise_error(Handsoap::Fault, error_msg)
56
+ end.should raise_error(EWS::ResponseError, /Id is malformed/)
50
57
  end
51
58
  end
52
59
 
@@ -64,11 +71,10 @@ describe 'Integration Tests' do
64
71
  EWS::Service.get_folder(:inbox).should be_instance_of(EWS::Folder)
65
72
  end
66
73
 
67
- it "should raise a SoapError when the ResponseMessage is an Error" do
68
- error_msg = /The value 'does-not-exist' is invalid according to its datatype/
74
+ it "should raise a ResponseError when the folder does not exist" do
69
75
  lambda do
70
76
  EWS::Service.get_folder('does-not-exist')
71
- end.should raise_error(Handsoap::Fault, error_msg)
77
+ end.should raise_error(EWS::ResponseError, /Id is malformed/)
72
78
  end
73
79
  end
74
80
 
@@ -83,11 +89,10 @@ describe 'Integration Tests' do
83
89
  items.should be_instance_of(Array)
84
90
  end
85
91
 
86
- it "should raise a Fault when the item does not exist" do
87
- error_msg = /The value 'does-not-exist' is invalid according to its datatype/
92
+ it "should raise a ResponseError when the item does not exist" do
88
93
  lambda do
89
94
  EWS::Service.find_item('does-not-exist')
90
- end.should raise_error(Handsoap::Fault, error_msg)
95
+ end.should raise_error(EWS::ResponseError, /Id is malformed/)
91
96
  end
92
97
  end
93
98
 
@@ -130,9 +135,8 @@ describe 'Integration Tests' do
130
135
 
131
136
  context 'move_item' do
132
137
  #it "should move the item" do
133
- # folder_id = 'AQAUAHRlc3RxZHNib3VuY2VAcWcuY29tAC4AAAMXckeXPuMKT4uj0fYRoj0SAQAUIOj2Wr1iR63wVBJuRuVLABU0TWDnAAAA'
134
- #
135
- # id = 'AAAUAHRlc3RxZHNib3VuY2VAcWcuY29tAEYAAAAAABdyR5c+4wpPi6PR9hGiPRIHABQg6PZavWJHrfBUEm5G5UsAFTRNedwAABQg6PZavWJHrfBUEm5G5UsAFTRNhHAAAA=='
138
+ # folder_id =
139
+ # id =
136
140
  #
137
141
  # EWS::Service.move_item!(folder_id, [id])
138
142
  # end
@@ -4,7 +4,10 @@ require 'ews-api'
4
4
  require 'spec'
5
5
  require 'spec/autorun'
6
6
 
7
- module EWS::SpecHelper
7
+ TNS = %q|xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"|
8
+ MNS = %q|xmlns:tns="http://schemas.microsoft.com/exchange/services/2006/messages"|
9
+
10
+ module EWS::SpecHelper
8
11
  def fixtures
9
12
  @fixtures ||= Dir[File.dirname(__FILE__) + '/fixtures/*.xml'].inject({}) do |fixtures, f|
10
13
  fixtures[File.basename(f).chomp('.xml')] = File.expand_path(f)
@@ -54,6 +57,13 @@ module EWS::SpecHelper
54
57
  </soap:Envelope>
55
58
  EOS
56
59
  end
60
+
61
+ def new_document
62
+ doc = Handsoap::XmlMason::Document.new
63
+ doc.xml_header = nil
64
+ EWS::Service.register_aliases! doc
65
+ doc
66
+ end
57
67
  end
58
68
 
59
69
  Spec::Runner.configure do |config|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ews-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.a
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - jrun
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-17 00:00:00 -06:00
12
+ date: 2010-01-25 00:00:00 -06:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -40,7 +40,7 @@ dependencies:
40
40
  requirements:
41
41
  - - "="
42
42
  - !ruby/object:Gem::Version
43
- version: 1.1.4
43
+ version: 1.1.6
44
44
  version:
45
45
  - !ruby/object:Gem::Dependency
46
46
  name: rspec
@@ -81,6 +81,10 @@ files:
81
81
  - ews-api.gemspec
82
82
  - lib/ews-api.rb
83
83
  - lib/ews/attachment.rb
84
+ - lib/ews/builder.rb
85
+ - lib/ews/builders/resolve_names_builder.rb
86
+ - lib/ews/builders/shape_builder.rb
87
+ - lib/ews/distinguished_folders.rb
84
88
  - lib/ews/error.rb
85
89
  - lib/ews/folder.rb
86
90
  - lib/ews/message.rb
@@ -88,6 +92,9 @@ files:
88
92
  - lib/ews/parser.rb
89
93
  - lib/ews/service.rb
90
94
  - spec/ews/attachment_spec.rb
95
+ - spec/ews/builder_spec.rb
96
+ - spec/ews/builders/resolve_names_builder_spec.rb
97
+ - spec/ews/builders/shape_builder_spec.rb
91
98
  - spec/ews/folder_spec.rb
92
99
  - spec/ews/message_spec.rb
93
100
  - spec/ews/model_spec.rb
@@ -107,7 +114,7 @@ files:
107
114
  - spec/spec.opts
108
115
  - spec/spec_helper.rb
109
116
  has_rdoc: true
110
- homepage: http://github.com/jrun/ews-api
117
+ homepage: http://jrun.github.com/ews-api/ews
111
118
  licenses: []
112
119
 
113
120
  post_install_message:
@@ -123,9 +130,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
123
130
  version:
124
131
  required_rubygems_version: !ruby/object:Gem::Requirement
125
132
  requirements:
126
- - - ">"
133
+ - - ">="
127
134
  - !ruby/object:Gem::Version
128
- version: 1.3.1
135
+ version: "0"
129
136
  version:
130
137
  requirements: []
131
138
 
@@ -139,7 +146,10 @@ test_files:
139
146
  - spec/integration.rb
140
147
  - spec/ews/parser_spec.rb
141
148
  - spec/ews/message_spec.rb
149
+ - spec/ews/builder_spec.rb
142
150
  - spec/ews/attachment_spec.rb
143
151
  - spec/ews/folder_spec.rb
144
152
  - spec/ews/service_spec.rb
153
+ - spec/ews/builders/resolve_names_builder_spec.rb
154
+ - spec/ews/builders/shape_builder_spec.rb
145
155
  - spec/ews/model_spec.rb