This really does like to yell at me.
This commit is contained in:
parent
61c006118a
commit
f77f773b60
18 changed files with 414 additions and 125 deletions
11
.gitignore
vendored
11
.gitignore
vendored
|
@ -1,8 +1,19 @@
|
||||||
/.bundle/
|
/.bundle/
|
||||||
/.yardoc
|
/.yardoc
|
||||||
|
/Gemfile.lock
|
||||||
/_yardoc/
|
/_yardoc/
|
||||||
/coverage/
|
/coverage/
|
||||||
/doc/
|
/doc/
|
||||||
/pkg/
|
/pkg/
|
||||||
/spec/reports/
|
/spec/reports/
|
||||||
/tmp/
|
/tmp/
|
||||||
|
/.ruby-version
|
||||||
|
/.ruby-gemset
|
||||||
|
/.rvm
|
||||||
|
*.bundle
|
||||||
|
*.so
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
mkmf.log
|
||||||
|
scratch.rb
|
||||||
|
*.sw[op]
|
15
.idea/autodiscover.iml
generated
15
.idea/autodiscover.iml
generated
|
@ -1,15 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="RUBY_MODULE" version="4">
|
|
||||||
<component name="ModuleRunConfigurationManager">
|
|
||||||
<shared />
|
|
||||||
</component>
|
|
||||||
<component name="NewModuleRootManager">
|
|
||||||
<content url="file://$MODULE_DIR$">
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/features" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
|
||||||
</content>
|
|
||||||
<orderEntry type="jdk" jdkName="ruby-3.2.3-p157" jdkType="RUBY_SDK" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
8
Gemfile
8
Gemfile
|
@ -1,10 +1,4 @@
|
||||||
# frozen_string_literal: true
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
source "https://rubygems.org"
|
|
||||||
|
|
||||||
# Specify your gem's dependencies in autodiscover.gemspec
|
# Specify your gem's dependencies in autodiscover.gemspec
|
||||||
gemspec
|
gemspec
|
||||||
|
|
||||||
gem "rake", "~> 13.0"
|
|
||||||
|
|
||||||
gem "minitest", "~> 5.16"
|
|
||||||
|
|
21
Rakefile
21
Rakefile
|
@ -1,8 +1,19 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require "bundler/gem_tasks"
|
require "bundler/gem_tasks"
|
||||||
require "minitest/test_task"
|
require "rake/testtask"
|
||||||
|
|
||||||
Minitest::TestTask.create
|
task :default => :test
|
||||||
|
|
||||||
task default: :test
|
Rake::TestTask.new(:test) do |t|
|
||||||
|
t.libs << 'lib'
|
||||||
|
t.libs << 'test'
|
||||||
|
t.pattern = 'test/**/*_test.rb'
|
||||||
|
t.verbose = false
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "Open a Pry console for this library"
|
||||||
|
task :console do
|
||||||
|
require "pry"
|
||||||
|
require "autodiscover"
|
||||||
|
ARGV.clear
|
||||||
|
Pry.start
|
||||||
|
end
|
|
@ -1,40 +1,32 @@
|
||||||
# frozen_string_literal: true
|
# coding: utf-8
|
||||||
|
lib = File.expand_path('../lib', __FILE__)
|
||||||
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||||
|
require 'autodiscover/version'
|
||||||
|
|
||||||
require_relative "lib/autodiscover/version"
|
Gem::Specification.new do |s|
|
||||||
|
s.name = 'autodiscover'
|
||||||
|
s.version = Autodiscover::VERSION
|
||||||
|
s.license = 'MIT'
|
||||||
|
s.summary = "Ruby client for Microsoft's Autodiscover Service"
|
||||||
|
s.description = "The Autodiscover Service provides information about a Microsoft Exchange environment such as service URLs, versions and many other attributes."
|
||||||
|
s.required_ruby_version = '>= 2.1.0'
|
||||||
|
|
||||||
Gem::Specification.new do |spec|
|
s.authors = ["David King", "Dan Wanek"]
|
||||||
spec.name = "autodiscover"
|
s.email = ["dking@bestinclass.com", "dan.wanek@gmail.com"]
|
||||||
spec.version = Autodiscover::VERSION
|
s.homepage = 'http://github.com/WinRb/autodiscover'
|
||||||
spec.authors = ["Toastie"]
|
|
||||||
spec.email = ["toastie@toastiet0ast.com"]
|
|
||||||
|
|
||||||
spec.summary = "TODO: Write a short summary, because RubyGems requires one."
|
s.files = `git ls-files -z`.split("\x0")
|
||||||
spec.description = "TODO: Write a longer description or delete this line."
|
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
||||||
spec.homepage = "TODO: Put your gem's website or public repo URL here."
|
s.require_paths = ["lib"]
|
||||||
spec.license = "MIT"
|
|
||||||
spec.required_ruby_version = ">= 3.0.0"
|
|
||||||
|
|
||||||
spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
|
s.add_runtime_dependency "nokogiri"
|
||||||
|
s.add_runtime_dependency "nori"
|
||||||
|
s.add_runtime_dependency "httpclient"
|
||||||
|
s.add_runtime_dependency "logging"
|
||||||
|
|
||||||
spec.metadata["homepage_uri"] = spec.homepage
|
s.add_development_dependency "minitest", "~> 5.6.0"
|
||||||
spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
|
s.add_development_dependency "mocha", "~> 1.1.0"
|
||||||
spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
|
s.add_development_dependency "bundler"
|
||||||
|
s.add_development_dependency "rake"
|
||||||
# Specify which files should be added to the gem when it is released.
|
s.add_development_dependency "pry"
|
||||||
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
||||||
spec.files = Dir.chdir(__dir__) do
|
|
||||||
`git ls-files -z`.split("\x0").reject do |f|
|
|
||||||
(File.expand_path(f) == __FILE__) ||
|
|
||||||
f.start_with?(*%w[bin/ test/ spec/ features/ .git appveyor Gemfile])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
spec.bindir = "exe"
|
|
||||||
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
||||||
spec.require_paths = ["lib"]
|
|
||||||
|
|
||||||
# Uncomment to register a new dependency of your gem
|
|
||||||
# spec.add_dependency "example-gem", "~> 1.0"
|
|
||||||
|
|
||||||
# For more information and examples about making a new gem, check out our
|
|
||||||
# guide at: https://bundler.io/guides/creating_gem.html
|
|
||||||
end
|
end
|
|
@ -1,8 +1,23 @@
|
||||||
# frozen_string_literal: true
|
require "autodiscover/version"
|
||||||
|
require "nokogiri"
|
||||||
require_relative "autodiscover/version"
|
require "nori"
|
||||||
|
require "httpclient"
|
||||||
|
require "logging"
|
||||||
|
|
||||||
module Autodiscover
|
module Autodiscover
|
||||||
class Error < StandardError; end
|
Logging.logger["Autodiscover"].level = :info
|
||||||
# Your code goes here...
|
|
||||||
|
def self.Logger
|
||||||
|
Logging.logger["Autodiscover"]
|
||||||
|
end
|
||||||
|
|
||||||
|
def logger
|
||||||
|
@logger ||= Logging.logger[self.class.name]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
require "autodiscover/errors"
|
||||||
|
require "autodiscover/client"
|
||||||
|
require "autodiscover/pox_request"
|
||||||
|
require "autodiscover/pox_response"
|
||||||
|
require "autodiscover/server_version_parser"
|
||||||
|
|
|
@ -1,4 +1,34 @@
|
||||||
# frozen_string_literal: true
|
module Autodiscover
|
||||||
|
class Client
|
||||||
|
DEFAULT_HTTP_TIMEOUT = 10
|
||||||
|
attr_accessor :domain, :email, :http
|
||||||
|
|
||||||
class Client
|
# @param email [String] An e-mail to use for autodiscovery. It will be
|
||||||
|
# used as the default username.
|
||||||
|
# @param password [String]
|
||||||
|
# @param username [String] An optional username if you want to authenticate
|
||||||
|
# with something other than the e-mail. For instance DOMAIN\user
|
||||||
|
# @param domain [String] An optional domain to provide as an override for
|
||||||
|
# the one parsed from the e-mail.
|
||||||
|
def initialize(email:, password:, username: nil, domain: nil, connect_timeout: DEFAULT_HTTP_TIMEOUT)
|
||||||
|
@email = email
|
||||||
|
@domain = domain || @email.split('@').last
|
||||||
|
@http = HTTPClient.new
|
||||||
|
@http.connect_timeout = connect_timeout if connect_timeout
|
||||||
|
@username = username || @email
|
||||||
|
@http.set_auth(nil, @username, password)
|
||||||
|
end
|
||||||
|
|
||||||
|
# @param type [Symbol] The type of response. Right now this is just :pox
|
||||||
|
# @param [Hash] **options
|
||||||
|
def autodiscover(type: :pox, **options)
|
||||||
|
case type
|
||||||
|
when :pox
|
||||||
|
PoxRequest.new(self, **options).autodiscover
|
||||||
|
else
|
||||||
|
raise Autodiscover::ArgumentError, "Not a valid autodiscover type (#{type})."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
|
@ -1,2 +1,4 @@
|
||||||
# frozen_string_literal: true
|
module Autodiscover
|
||||||
|
Logging.logger["Autodiscover"].level = :debug
|
||||||
|
Logging.logger["Autodiscover"].appenders = Logging.appenders.stdout
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
module Autodiscover
|
||||||
|
class Error < ::StandardError; end
|
||||||
|
|
||||||
|
class ArgumentError < Error; end
|
||||||
|
end
|
|
@ -1,4 +1,77 @@
|
||||||
# frozen_string_literal: true
|
module Autodiscover
|
||||||
|
class PoxRequest
|
||||||
|
include Autodiscover
|
||||||
|
|
||||||
module PoxRequest
|
attr_reader :client, :options
|
||||||
|
|
||||||
|
# @param client [Autodiscover::Client]
|
||||||
|
# @param [Hash] **options
|
||||||
|
# @option **options [Boolean] :ignore_ssl_errors Whether to keep trying if
|
||||||
|
# there are SSL errors
|
||||||
|
def initialize(client, **options)
|
||||||
|
@client = client
|
||||||
|
@options = options
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [Autodiscover::PoxResponse, nil]
|
||||||
|
def autodiscover
|
||||||
|
available_urls.each do |url|
|
||||||
|
response = client.http.post(url, request_body, {'Content-Type' => 'text/xml; charset=utf-8'})
|
||||||
|
return PoxResponse.new(response.body) if good_response?(response)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def good_response?(response)
|
||||||
|
response.status == 200
|
||||||
|
end
|
||||||
|
|
||||||
|
def available_urls(&block)
|
||||||
|
return to_enum(__method__) unless block_given?
|
||||||
|
formatted_https_urls.each {|url|
|
||||||
|
logger.debug "Yielding HTTPS Url #{url}"
|
||||||
|
handle_allowed_errors do
|
||||||
|
yield url
|
||||||
|
end
|
||||||
|
}
|
||||||
|
handle_allowed_errors do
|
||||||
|
logger.debug "Yielding HTTP Redirected Url #{redirected_http_url}"
|
||||||
|
yield redirected_http_url
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def formatted_https_urls
|
||||||
|
@formatted_urls ||= %W{
|
||||||
|
https://#{client.domain}/autodiscover/autodiscover.xml
|
||||||
|
https://autodiscover.#{client.domain}/autodiscover/autodiscover.xml
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def redirected_http_url
|
||||||
|
@redirected_http_url ||=
|
||||||
|
begin
|
||||||
|
response = client.http.get("http://autodiscover.#{client.domain}/autodiscover/autodiscover.xml")
|
||||||
|
(response.status == 302) ? response.headers["Location"] : nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def request_body
|
||||||
|
Nokogiri::XML::Builder.new do |xml|
|
||||||
|
xml.Autodiscover('xmlns' => 'http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006') {
|
||||||
|
xml.Request {
|
||||||
|
xml.EMailAddress client.email
|
||||||
|
xml.AcceptableResponseSchema 'http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end.to_xml
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_allowed_errors
|
||||||
|
yield
|
||||||
|
rescue SocketError, Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ECONNREFUSED, HTTPClient::ConnectTimeoutError
|
||||||
|
rescue OpenSSL::SSL::SSLError
|
||||||
|
raise if !options[:ignore_ssl_errors]
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
|
@ -1,4 +1,32 @@
|
||||||
# frozen_string_literal: true
|
module Autodiscover
|
||||||
|
class PoxResponse
|
||||||
|
|
||||||
class PoxResponse
|
attr_reader :response
|
||||||
|
|
||||||
|
def initialize(response)
|
||||||
|
raise ArgumentError, "Response must be an XML string" if(response.nil? || response.empty?)
|
||||||
|
@response = Nori.new(parser: :nokogiri).parse(response)["Autodiscover"]["Response"]
|
||||||
|
end
|
||||||
|
|
||||||
|
def exchange_version
|
||||||
|
ServerVersionParser.new(exch_proto["ServerVersion"]).exchange_version
|
||||||
|
end
|
||||||
|
|
||||||
|
def ews_url
|
||||||
|
expr_proto["EwsUrl"]
|
||||||
|
end
|
||||||
|
|
||||||
|
def exch_proto
|
||||||
|
@exch_proto ||= (response["Account"]["Protocol"].select{|p| p["Type"] == "EXCH"}.first || {})
|
||||||
|
end
|
||||||
|
|
||||||
|
def expr_proto
|
||||||
|
@expr_proto ||= (response["Account"]["Protocol"].select{|p| p["Type"] == "EXPR"}.first || {})
|
||||||
|
end
|
||||||
|
|
||||||
|
def web_proto
|
||||||
|
@web_proto ||= (response["Account"]["Protocol"].select{|p| p["Type"] == "WEB"}.first || {})
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
|
@ -1,4 +1,45 @@
|
||||||
# frozen_string_literal: true
|
module Autodiscover
|
||||||
|
class ServerVersionParser
|
||||||
|
|
||||||
class ServerVersionParser
|
VERSIONS = {
|
||||||
|
8 => {
|
||||||
|
0 => "Exchange2007",
|
||||||
|
1 => "Exchange2007_SP1",
|
||||||
|
2 => "Exchange2007_SP1",
|
||||||
|
3 => "Exchange2007_SP1",
|
||||||
|
},
|
||||||
|
14 => {
|
||||||
|
0 => "Exchange2010",
|
||||||
|
1 => "Exchange2010_SP1",
|
||||||
|
2 => "Exchange2010_SP2",
|
||||||
|
3 => "Exchange2010_SP2",
|
||||||
|
},
|
||||||
|
15 => {
|
||||||
|
0 => "Exchange2013",
|
||||||
|
1 => "Exchange2013_SP1",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def initialize(hexversion)
|
||||||
|
@version = hexversion.hex.to_s(2).rjust(hexversion.size*4, '0')
|
||||||
|
end
|
||||||
|
|
||||||
|
def major
|
||||||
|
@version[4..9].to_i(2)
|
||||||
|
end
|
||||||
|
|
||||||
|
def minor
|
||||||
|
@version[10..15].to_i(2)
|
||||||
|
end
|
||||||
|
|
||||||
|
def build
|
||||||
|
@version[17..31].to_i(2)
|
||||||
|
end
|
||||||
|
|
||||||
|
def exchange_version
|
||||||
|
v = VERSIONS[major][minor]
|
||||||
|
v.nil? ? VERIONS[8][0] : v
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
|
@ -1,5 +1,3 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module Autodiscover
|
module Autodiscover
|
||||||
VERSION = "0.1.0"
|
VERSION = "1.0.2"
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
# frozen_string_literal: true
|
require File.expand_path('../../lib/autodiscover.rb', __FILE__)
|
||||||
|
require 'minitest/autorun'
|
||||||
$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
|
|
||||||
require "autodiscover"
|
|
||||||
|
|
||||||
require "minitest/autorun"
|
require "minitest/autorun"
|
||||||
|
require "mocha/mini_test"
|
||||||
|
|
||||||
|
TEST_DIR = File.dirname(__FILE__)
|
||||||
|
|
||||||
|
class MiniTest::Spec
|
||||||
|
def load_sample(name)
|
||||||
|
File.read("#{TEST_DIR}/fixtures/#{name}")
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,17 +1,35 @@
|
||||||
# frozen_string_literal: true
|
require "test_helper"
|
||||||
|
|
||||||
require 'minitest/autorun'
|
describe Autodiscover::Client do
|
||||||
|
let(:_class) { Autodiscover::Client }
|
||||||
|
|
||||||
class ClientTest < Minitest::Test
|
describe "#initialize" do
|
||||||
def setup
|
it "sets a username and domain from the email" do
|
||||||
# Do nothing
|
inst = _class.new(email: "test@example.local", password: "test")
|
||||||
|
_(inst.domain).must_equal "example.local"
|
||||||
|
_(inst.instance_variable_get(:@username)).must_equal "test@example.local"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows you to override the username and domain" do
|
||||||
|
inst = _class.new(email: "test@example.local", password: "test", username: 'DOMAIN\test', domain: "otherexample.local")
|
||||||
|
_(inst.domain).must_equal "otherexample.local"
|
||||||
|
_(inst.instance_variable_get(:@username)).must_equal 'DOMAIN\test'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def teardown
|
describe "#autodiscover" do
|
||||||
# Do nothing
|
it "dispatches autodiscover to a PoxRequest instance" do
|
||||||
|
inst = _class.new(email: "test@example.local", password: "test")
|
||||||
|
pox_request = mock("pox")
|
||||||
|
pox_request.expects(:autodiscover)
|
||||||
|
Autodiscover::PoxRequest.expects(:new).with(inst,{}).returns(pox_request)
|
||||||
|
inst.autodiscover
|
||||||
|
end
|
||||||
|
|
||||||
|
it "raises an exception if an invalid autodiscover type is passed" do
|
||||||
|
inst = _class.new(email: "test@example.local", password: "test")
|
||||||
|
->{ inst.autodiscover(type: :invalid) }.must_raise(Autodiscover::ArgumentError)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test
|
|
||||||
skip 'Not implemented'
|
|
||||||
end
|
|
||||||
end
|
end
|
|
@ -1,4 +1,46 @@
|
||||||
# frozen_string_literal: true
|
require "test_helper"
|
||||||
|
require "ostruct"
|
||||||
|
|
||||||
class PoxRequestTest
|
describe Autodiscover::PoxRequest do
|
||||||
|
let(:_class) {Autodiscover::PoxRequest }
|
||||||
|
let(:http) { mock("http") }
|
||||||
|
let(:client) { OpenStruct.new({http: http, domain: "example.local", email: "test@example.local"}) }
|
||||||
|
|
||||||
|
describe "#autodiscover" do
|
||||||
|
it "returns a PoxResponse if the autodiscover is successful" do
|
||||||
|
request_body = <<-EOF.gsub(/^ /,"")
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006">
|
||||||
|
<Request>
|
||||||
|
<EMailAddress>test@example.local</EMailAddress>
|
||||||
|
<AcceptableResponseSchema>http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a</AcceptableResponseSchema>
|
||||||
|
</Request>
|
||||||
|
</Autodiscover>
|
||||||
|
EOF
|
||||||
|
http.expects(:post).with(
|
||||||
|
"https://example.local/autodiscover/autodiscover.xml", request_body,
|
||||||
|
{'Content-Type' => 'text/xml; charset=utf-8'}
|
||||||
|
).returns(OpenStruct.new({status: 200, body: "<Autodiscover><Response><test></test></Response></Autodiscover>"}))
|
||||||
|
|
||||||
|
inst = _class.new(client)
|
||||||
|
_(inst.autodiscover).must_be_instance_of(Autodiscover::PoxResponse)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "will fail if :ignore_ssl_errors is not true" do
|
||||||
|
http.expects(:post).raises(OpenSSL::SSL::SSLError, "Test Error")
|
||||||
|
inst = _class.new(client)
|
||||||
|
-> {inst.autodiscover}.must_raise(OpenSSL::SSL::SSLError)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "keeps trying if :ignore_ssl_errors is set" do
|
||||||
|
http.expects(:get).once.returns(OpenStruct.new({headers: {"Location" => "http://example.local"}, status: 302}))
|
||||||
|
http.expects(:post).times(3).
|
||||||
|
raises(OpenSSL::SSL::SSLError, "Test Error").then.
|
||||||
|
raises(OpenSSL::SSL::SSLError, "Test Error").then.
|
||||||
|
raises(Errno::ENETUNREACH, "Test Error")
|
||||||
|
inst = _class.new(client, ignore_ssl_errors: true)
|
||||||
|
_(inst.autodiscover).must_be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
|
@ -1,17 +1,54 @@
|
||||||
# frozen_string_literal: true
|
require "test_helper"
|
||||||
|
|
||||||
require 'minitest/autorun'
|
describe Autodiscover::PoxResponse do
|
||||||
|
let(:_class) {Autodiscover::PoxResponse }
|
||||||
|
let(:response) { load_sample("pox_response.xml") }
|
||||||
|
|
||||||
class PoxResponseTest < Minitest::Test
|
describe "#initialize" do
|
||||||
def setup
|
it "parses an XML string into a Hash when initialized" do
|
||||||
# Do nothing
|
inst = _class.new response
|
||||||
|
_(inst.response).must_be_instance_of Hash
|
||||||
|
end
|
||||||
|
|
||||||
|
it "it raises an exception if the response is empty or nil" do
|
||||||
|
->{_class.new ""}.must_raise(Autodiscover::ArgumentError)
|
||||||
|
->{_class.new nil}.must_raise(Autodiscover::ArgumentError)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def teardown
|
describe "#exchange_version" do
|
||||||
# Do nothing
|
it "returns an Exchange version usable for EWS" do
|
||||||
|
_(_class.new(response).exchange_version).must_equal "Exchange2013_SP1"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test
|
describe "#ews_url" do
|
||||||
skip 'Not implemented'
|
it "returns the EWS url" do
|
||||||
|
_(_class.new(response).ews_url).must_equal "https://outlook.office365.com/EWS/Exchange.asmx"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "Protocol Hashes" do
|
||||||
|
let(:_inst) { _class.new(response) }
|
||||||
|
|
||||||
|
it "returns the EXCH protocol Hash" do
|
||||||
|
_(_inst.exch_proto["Type"]).must_equal "EXCH"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns the EXPR protocol Hash" do
|
||||||
|
_(_inst.expr_proto["Type"]).must_equal "EXPR"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns the WEB protocol Hash" do
|
||||||
|
_(_inst.web_proto["Type"]).must_equal "WEB"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns empty Hashes when the protocols are missing" do
|
||||||
|
_inst.response["Account"]["Protocol"] = []
|
||||||
|
_(_inst.exch_proto).must_equal({})
|
||||||
|
_(_inst.expr_proto).must_equal({})
|
||||||
|
_(_inst.web_proto).must_equal({})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
|
@ -1,17 +1,18 @@
|
||||||
# frozen_string_literal: true
|
require "test_helper"
|
||||||
|
|
||||||
require 'minitest/autorun'
|
describe Autodiscover::ServerVersionParser do
|
||||||
|
let(:_class) { Autodiscover::ServerVersionParser }
|
||||||
|
|
||||||
class ServerVersionParserTest < Minitest::Test
|
it "parses a hex ServerVersion response" do
|
||||||
def setup
|
inst = _class.new("738180DA")
|
||||||
# Do nothing
|
_(inst.major).must_equal 14
|
||||||
|
_(inst.minor).must_equal 1
|
||||||
|
_(inst.build).must_equal 218
|
||||||
end
|
end
|
||||||
|
|
||||||
def teardown
|
it "returns an Exchange Server Version" do
|
||||||
# Do nothing
|
inst = _class.new("738180DA")
|
||||||
|
inst.exchange_version.must_equal "Exchange2010_SP1"
|
||||||
end
|
end
|
||||||
|
|
||||||
def test
|
|
||||||
skip 'Not implemented'
|
|
||||||
end
|
|
||||||
end
|
end
|
Loading…
Add table
Add a link
Reference in a new issue