ews-api 0.1.0.a → 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/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