Really fix regression introduced in 23879bc (fixes #2220)
This commit is contained in:
parent
19319d9d83
commit
b58fcbb5fc
12 changed files with 23836 additions and 58 deletions
3
Gemfile
3
Gemfile
|
@ -164,8 +164,9 @@ group :development, :test do
|
|||
# mock http calls
|
||||
gem 'webmock'
|
||||
|
||||
# record and replay TCP transactions
|
||||
# record and replay TCP/HTTP transactions
|
||||
gem 'tcr'
|
||||
gem 'vcr'
|
||||
end
|
||||
|
||||
# Want to extend Zammad with additional gems?
|
||||
|
|
|
@ -461,6 +461,7 @@ GEM
|
|||
valid_email2 (2.1.0)
|
||||
activemodel (>= 3.2)
|
||||
mail (~> 2.5)
|
||||
vcr (4.0.0)
|
||||
viewpoint (1.1.0)
|
||||
httpclient
|
||||
logging
|
||||
|
@ -565,6 +566,7 @@ DEPENDENCIES
|
|||
uglifier
|
||||
unicorn
|
||||
valid_email2
|
||||
vcr
|
||||
viewpoint
|
||||
webmock
|
||||
writeexcel
|
||||
|
|
|
@ -25,8 +25,7 @@ module Import
|
|||
end
|
||||
|
||||
def find(id)
|
||||
(@lookup_map[id] ||= @connection.get_folder(id)) ||
|
||||
id_folder_map[id]
|
||||
@lookup_map[id] ||= @connection.get_folder(id)
|
||||
end
|
||||
|
||||
def all
|
||||
|
@ -43,8 +42,8 @@ module Import
|
|||
end
|
||||
|
||||
def display_path(folder)
|
||||
display_name = folder.display_name&.utf8_encode(fallback: :read_as_sanitized_binary)
|
||||
parent_folder = find(folder.parent_folder_id)
|
||||
display_name = folder.display_name.utf8_encode(fallback: :read_as_sanitized_binary)
|
||||
parent_folder = id_folder_map[folder.parent_folder_id]
|
||||
|
||||
return display_name if parent_folder.blank?
|
||||
|
||||
|
|
|
@ -2,81 +2,74 @@ require 'rails_helper'
|
|||
|
||||
RSpec.describe Import::Exchange::Folder do
|
||||
# see https://github.com/zammad/zammad/issues/2152
|
||||
# WARNING! This test is closely tied to the implementation. :(
|
||||
describe '#display_path (#2152)' do
|
||||
let(:subject) { described_class.new(connection) }
|
||||
let(:connection) { instance_double('Viewpoint::EWSClient') }
|
||||
let(:root_folder) { double('EWS Folder') }
|
||||
let(:child_folder) { double('EWS Folder') }
|
||||
let(:exception_case) { double('EWS Folder') }
|
||||
let(:subject) { described_class.new(ews_connection) }
|
||||
let(:ews_connection) { Viewpoint::EWSClient.new(endpoint, user, pass) }
|
||||
let(:endpoint) { 'https://exchange.example.com/EWS/Exchange.asmx' }
|
||||
let(:user) { 'user@example.com' }
|
||||
let(:pass) { 'password' }
|
||||
let(:grandchild_of_root) { ews_connection.get_folder_by_name('Inbox') }
|
||||
let(:child_of_root) { ews_connection.get_folder(grandchild_of_root.parent_folder_id) }
|
||||
|
||||
context 'when folder.display_name returns nil' do
|
||||
before do
|
||||
allow(root_folder).to receive(:display_name).and_return(nil)
|
||||
allow(root_folder).to receive(:parent_folder_id).and_return(nil)
|
||||
|
||||
allow(subject).to receive(:find).with(any_args).and_return(root_folder)
|
||||
allow(subject).to receive(:find).with(nil).and_return(nil)
|
||||
end
|
||||
|
||||
it 'returns nil' do
|
||||
expect(subject.display_path(root_folder)).to be(nil)
|
||||
end
|
||||
around do |example|
|
||||
cassette_name = example.description.gsub(/[^0-9A-Za-z.\-]+/, '_')
|
||||
VCR.use_cassette("lib/import/exchange/folder/#{cassette_name}") { example.run }
|
||||
end
|
||||
|
||||
context 'when server returns valid UTF-8' do
|
||||
before do
|
||||
allow(root_folder).to receive(:display_name).and_return('Root')
|
||||
allow(root_folder).to receive(:parent_folder_id).and_return(nil)
|
||||
|
||||
allow(child_folder).to receive(:display_name).and_return('Leaf')
|
||||
allow(child_folder).to receive(:parent_folder_id).and_return(1)
|
||||
|
||||
allow(exception_case).to receive(:display_name).and_return('Error-Raising Leaf')
|
||||
allow(exception_case).to receive(:parent_folder_id).and_raise(Viewpoint::EWS::EwsError)
|
||||
|
||||
allow(subject).to receive(:find).with(any_args).and_return(root_folder)
|
||||
allow(subject).to receive(:find).with(nil).and_return(nil)
|
||||
end
|
||||
|
||||
context 'and target folder is directory root' do
|
||||
context 'and target folder is in root directory' do
|
||||
it 'returns the display name of the folder' do
|
||||
expect(subject.display_path(root_folder)).to eq('Root')
|
||||
expect(subject.display_path(child_of_root))
|
||||
.to eq('Top of Information Store')
|
||||
end
|
||||
end
|
||||
|
||||
context 'and target folder is NOT directory root' do
|
||||
context 'and target folder is in subfolder of root' do
|
||||
it 'returns the full path from root to target' do
|
||||
expect(subject.display_path(child_folder)).to eq('Root -> Leaf')
|
||||
expect(subject.display_path(grandchild_of_root))
|
||||
.to eq('Top of Information Store -> Inbox')
|
||||
end
|
||||
end
|
||||
|
||||
context 'and walking up directory tree raises EwsError' do
|
||||
it 'returns the partial path from error to target folder' do
|
||||
expect(subject.display_path(exception_case)).to eq('Error-Raising Leaf')
|
||||
allow(subject)
|
||||
.to receive(:id_folder_map).with(any_args).and_raise(Viewpoint::EWS::EwsError)
|
||||
|
||||
expect(subject.display_path(grandchild_of_root))
|
||||
.to eq('Inbox')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when server returns invalid UTF-8' do
|
||||
before do
|
||||
allow(root_folder).to receive(:display_name).and_return('你好'.b)
|
||||
allow(root_folder).to receive(:parent_folder_id).and_return(nil)
|
||||
context 'and target folder is in root directory' do
|
||||
it 'returns the display name of the folder in valid UTF-8' do
|
||||
allow(child_of_root)
|
||||
.to receive(:display_name).and_return('你好'.b)
|
||||
|
||||
allow(child_folder).to receive(:display_name).and_return('你好'.b)
|
||||
allow(child_folder).to receive(:parent_folder_id).and_return(1)
|
||||
|
||||
allow(exception_case).to receive(:display_name).and_return('你好'.b)
|
||||
allow(exception_case).to receive(:parent_folder_id).and_raise(Viewpoint::EWS::EwsError)
|
||||
|
||||
allow(subject).to receive(:find).with(any_args).and_return(root_folder)
|
||||
allow(subject).to receive(:find).with(nil).and_return(nil)
|
||||
expect { subject.display_path(child_of_root).to_json }.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns a valid UTF-8 string' do
|
||||
expect { subject.display_path(root_folder).to_json }.not_to raise_error
|
||||
expect { subject.display_path(child_folder).to_json }.not_to raise_error
|
||||
expect { subject.display_path(exception_case).to_json }.not_to raise_error
|
||||
context 'and target folder is in subfolder of root' do
|
||||
it 'returns the full path from root to target in valid UTF-8' do
|
||||
allow(grandchild_of_root)
|
||||
.to receive(:display_name).and_return('你好'.b)
|
||||
|
||||
expect { subject.display_path(grandchild_of_root).to_json }.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
context 'and walking up directory tree raises EwsError' do
|
||||
it 'returns the partial path from error to target folder in valid UTF-8' do
|
||||
allow(grandchild_of_root)
|
||||
.to receive(:display_name).and_return('你好'.b)
|
||||
allow(subject)
|
||||
.to receive(:id_folder_map).with(any_args).and_raise(Viewpoint::EWS::EwsError)
|
||||
|
||||
expect { subject.display_path(grandchild_of_root).to_json }.not_to raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
5
spec/support/vcr.rb
Normal file
5
spec/support/vcr.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
VCR.configure do |config|
|
||||
config.cassette_library_dir = 'test/data/vcr_cassettes'
|
||||
config.hook_into :webmock
|
||||
config.allow_http_connections_when_no_cassette = true
|
||||
end
|
|
@ -2,7 +2,7 @@
|
|||
# - Zammad webservices
|
||||
# - Google (calendar)
|
||||
allowed_sites = lambda do |uri|
|
||||
['zammad.com', 'google.com'].any? do |site|
|
||||
['zammad.com', 'google.com', 'exchange.example.com'].any? do |site|
|
||||
uri.host.include?(site)
|
||||
end
|
||||
end
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,97 @@
|
|||
---
|
||||
http_interactions:
|
||||
- request:
|
||||
method: post
|
||||
uri: https://exchange.example.com/EWS/Exchange.asmx
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: |
|
||||
<?xml version="1.0"?>
|
||||
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
|
||||
<soap:Header>
|
||||
<t:RequestServerVersion Version="Exchange2010"/>
|
||||
</soap:Header>
|
||||
<soap:Body>
|
||||
<FindFolder xmlns="http://schemas.microsoft.com/exchange/services/2006/messages" Traversal="Shallow">
|
||||
<FolderShape>
|
||||
<t:BaseShape>Default</t:BaseShape>
|
||||
</FolderShape>
|
||||
<m:Restriction>
|
||||
<t:IsEqualTo>
|
||||
<t:FieldURI FieldURI="folder:DisplayName"/>
|
||||
<t:FieldURIOrConstant>
|
||||
<t:Constant Value="Inbox"/>
|
||||
</t:FieldURIOrConstant>
|
||||
</t:IsEqualTo>
|
||||
</m:Restriction>
|
||||
<m:ParentFolderIds>
|
||||
<t:DistinguishedFolderId Id="msgfolderroot"/>
|
||||
</m:ParentFolderIds>
|
||||
</FindFolder>
|
||||
</soap:Body>
|
||||
</soap:Envelope>
|
||||
headers:
|
||||
User-Agent:
|
||||
- HTTPClient/1.0 (2.8.3, ruby 2.4.4 (2018-03-28))
|
||||
Accept:
|
||||
- "*/*"
|
||||
Date:
|
||||
- Tue, 04 Sep 2018 05:12:45 GMT
|
||||
Content-Type:
|
||||
- text/xml
|
||||
Cookie:
|
||||
- ClientId=TMH9PMQHUMIOL0RLW
|
||||
Authorization:
|
||||
- Negotiate TlRMTVNTUAADAAAAGAAYAEQAAADGAMYAXAAAAAAAAAAiAQAARABEACIBAAAAAAAAZgEAAAAAAABmAQAABYKJAgAAAACKsgCrRMWhrvDR0QJjG0Dtb4IfWD0Uc2cyO1jML/8FAggCPZ0gmtrTAQEAAAAAAACAxOXpDUTUAW+CH1g9FHNnAAAAAAIAEABFAFgAQwBIAEEATgBHAEUAAQAMAEUAWABGAEUAMAA2AAQAGABFAFgAQwBIAEEATgBHAEUALgBJAE4AVAADACYARQBYAEYARQAwADYALgBFAFgAQwBIAEEATgBHAEUALgBJAE4AVAAFABgARQBYAEMASABBAE4ARwBFAC4ASQBOAFQABwAIACN63+kNRNQBAAAAAAAAAABjAHUAcwB0AG8AbQBlAHIAMwBAAGEANQAzADEAMgA3ADQALgBlAHgAYwBoAGEAbgBnAGUALQBtAGEAaQBsAC4AZQB1AA==
|
||||
response:
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
headers:
|
||||
Cache-Control:
|
||||
- private
|
||||
Transfer-Encoding:
|
||||
- chunked
|
||||
Content-Type:
|
||||
- text/xml; charset=utf-8
|
||||
Server:
|
||||
- Microsoft-IIS/8.0
|
||||
Request-Id:
|
||||
- 9144d49b-057c-4840-8032-80911701fed9
|
||||
X-Calculatedbetarget:
|
||||
- exdag20-2.exchange.int
|
||||
X-Diaginfo:
|
||||
- EXDAG20-2
|
||||
X-Beserver:
|
||||
- EXDAG20-2
|
||||
X-Aspnet-Version:
|
||||
- 4.0.30319
|
||||
Set-Cookie:
|
||||
- X-BackEndCookie=S-1-5-21-2149852636-2334046265-983485362-135679=u56Lnp2ejJqBzpnGyczNzMjSy8nOydLLnJzM0seamc/SzMjJxs6bm8eazZnIgYHNz87H0s7P0s/Lq8/Kxc7NxcvK;
|
||||
expires=Thu, 04-Oct-2018 05:12:45 GMT; path=/EWS; secure; HttpOnly
|
||||
- exchangecookie=43aef8df84174a8098242a61c783c8ef; expires=Wed, 04-Sep-2019
|
||||
05:12:45 GMT; path=/; HttpOnly
|
||||
Persistent-Auth:
|
||||
- 'true'
|
||||
X-Powered-By:
|
||||
- ASP.NET
|
||||
X-Feserver:
|
||||
- EXFE06
|
||||
Date:
|
||||
- Tue, 04 Sep 2018 05:12:44 GMT
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: <?xml version="1.0" encoding="utf-8"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Header><h:ServerVersionInfo
|
||||
MajorVersion="15" MinorVersion="0" MajorBuildNumber="1293" MinorBuildNumber="6"
|
||||
Version="V2_23" xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types"
|
||||
xmlns="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/></s:Header><s:Body
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><m:FindFolderResponse
|
||||
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"><m:ResponseMessages><m:FindFolderResponseMessage
|
||||
ResponseClass="Success"><m:ResponseCode>NoError</m:ResponseCode><m:RootFolder
|
||||
TotalItemsInView="1" IncludesLastItemInRange="true"><t:Folders><t:Folder><t:FolderId
|
||||
Id="AQMkADRjMTk4NmJlLTNjMGUtNDk1Yy04MjAxLWE2Nzk0NWYzY2MANTcALgAAA9shP4dg44BKifl+6m/8GgMBALoafj1aZ5lBsuy9VYcX6tAAAAIBDAAAAA=="
|
||||
ChangeKey="AQAAABYAAAC6Gn49WmeZQbLsvVWHF+rQAAAAABsE"/><t:DisplayName>Inbox</t:DisplayName><t:TotalCount>0</t:TotalCount><t:ChildFolderCount>1</t:ChildFolderCount><t:UnreadCount>0</t:UnreadCount></t:Folder></t:Folders></m:RootFolder></m:FindFolderResponseMessage></m:ResponseMessages></m:FindFolderResponse></s:Body></s:Envelope>
|
||||
http_version:
|
||||
recorded_at: Tue, 04 Sep 2018 05:12:45 GMT
|
||||
recorded_with: VCR 4.0.0
|
|
@ -0,0 +1,97 @@
|
|||
---
|
||||
http_interactions:
|
||||
- request:
|
||||
method: post
|
||||
uri: https://exchange.example.com/EWS/Exchange.asmx
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: |
|
||||
<?xml version="1.0"?>
|
||||
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
|
||||
<soap:Header>
|
||||
<t:RequestServerVersion Version="Exchange2010"/>
|
||||
</soap:Header>
|
||||
<soap:Body>
|
||||
<FindFolder xmlns="http://schemas.microsoft.com/exchange/services/2006/messages" Traversal="Shallow">
|
||||
<FolderShape>
|
||||
<t:BaseShape>Default</t:BaseShape>
|
||||
</FolderShape>
|
||||
<m:Restriction>
|
||||
<t:IsEqualTo>
|
||||
<t:FieldURI FieldURI="folder:DisplayName"/>
|
||||
<t:FieldURIOrConstant>
|
||||
<t:Constant Value="Inbox"/>
|
||||
</t:FieldURIOrConstant>
|
||||
</t:IsEqualTo>
|
||||
</m:Restriction>
|
||||
<m:ParentFolderIds>
|
||||
<t:DistinguishedFolderId Id="msgfolderroot"/>
|
||||
</m:ParentFolderIds>
|
||||
</FindFolder>
|
||||
</soap:Body>
|
||||
</soap:Envelope>
|
||||
headers:
|
||||
User-Agent:
|
||||
- HTTPClient/1.0 (2.8.3, ruby 2.4.4 (2018-03-28))
|
||||
Accept:
|
||||
- "*/*"
|
||||
Date:
|
||||
- Tue, 04 Sep 2018 05:29:21 GMT
|
||||
Content-Type:
|
||||
- text/xml
|
||||
Cookie:
|
||||
- ClientId=E0YFFWDNP0GXXFCYTFUW
|
||||
Authorization:
|
||||
- Negotiate TlRMTVNTUAADAAAAGAAYAEQAAADGAMYAXAAAAAAAAAAiAQAARABEACIBAAAAAAAAZgEAAAAAAABmAQAABYKJAgAAAABMEJ04Cv8NvAxULJlH62pCu8GOV5tsEyoaVzgkOoBRqzPDFGW7sfpKAQEAAAAAAACATo87EETUAbvBjlebbBMqAAAAAAIAEABFAFgAQwBIAEEATgBHAEUAAQAMAEUAWABGAEUAMAA2AAQAGABFAFgAQwBIAEEATgBHAEUALgBJAE4AVAADACYARQBYAEYARQAwADYALgBFAFgAQwBIAEEATgBHAEUALgBJAE4AVAAFABgARQBYAEMASABBAE4ARwBFAC4ASQBOAFQABwAIAJ1LzDsQRNQBAAAAAAAAAABjAHUAcwB0AG8AbQBlAHIAMwBAAGEANQAzADEAMgA3ADQALgBlAHgAYwBoAGEAbgBnAGUALQBtAGEAaQBsAC4AZQB1AA==
|
||||
response:
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
headers:
|
||||
Cache-Control:
|
||||
- private
|
||||
Transfer-Encoding:
|
||||
- chunked
|
||||
Content-Type:
|
||||
- text/xml; charset=utf-8
|
||||
Server:
|
||||
- Microsoft-IIS/8.0
|
||||
Request-Id:
|
||||
- cf74b089-0c14-487e-9f18-15e65ba17d14
|
||||
X-Calculatedbetarget:
|
||||
- exdag20-2.exchange.int
|
||||
X-Diaginfo:
|
||||
- EXDAG20-2
|
||||
X-Beserver:
|
||||
- EXDAG20-2
|
||||
X-Aspnet-Version:
|
||||
- 4.0.30319
|
||||
Set-Cookie:
|
||||
- X-BackEndCookie=S-1-5-21-2149852636-2334046265-983485362-135679=u56Lnp2ejJqBzpnGyczNzMjSy8nOydLLnJzM0seamc/SzMjJxs6bm8eazZnIgYHNz87H0s7P0s/Lq8/Kxc3Gxc3O;
|
||||
expires=Thu, 04-Oct-2018 05:29:21 GMT; path=/EWS; secure; HttpOnly
|
||||
- exchangecookie=36481ec209524d17beb8a645d1e9a389; expires=Wed, 04-Sep-2019
|
||||
05:29:21 GMT; path=/; HttpOnly
|
||||
Persistent-Auth:
|
||||
- 'true'
|
||||
X-Powered-By:
|
||||
- ASP.NET
|
||||
X-Feserver:
|
||||
- EXFE06
|
||||
Date:
|
||||
- Tue, 04 Sep 2018 05:29:21 GMT
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: <?xml version="1.0" encoding="utf-8"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Header><h:ServerVersionInfo
|
||||
MajorVersion="15" MinorVersion="0" MajorBuildNumber="1293" MinorBuildNumber="6"
|
||||
Version="V2_23" xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types"
|
||||
xmlns="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/></s:Header><s:Body
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><m:FindFolderResponse
|
||||
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"><m:ResponseMessages><m:FindFolderResponseMessage
|
||||
ResponseClass="Success"><m:ResponseCode>NoError</m:ResponseCode><m:RootFolder
|
||||
TotalItemsInView="1" IncludesLastItemInRange="true"><t:Folders><t:Folder><t:FolderId
|
||||
Id="AQMkADRjMTk4NmJlLTNjMGUtNDk1Yy04MjAxLWE2Nzk0NWYzY2MANTcALgAAA9shP4dg44BKifl+6m/8GgMBALoafj1aZ5lBsuy9VYcX6tAAAAIBDAAAAA=="
|
||||
ChangeKey="AQAAABYAAAC6Gn49WmeZQbLsvVWHF+rQAAAAABsE"/><t:DisplayName>Inbox</t:DisplayName><t:TotalCount>0</t:TotalCount><t:ChildFolderCount>1</t:ChildFolderCount><t:UnreadCount>0</t:UnreadCount></t:Folder></t:Folders></m:RootFolder></m:FindFolderResponseMessage></m:ResponseMessages></m:FindFolderResponse></s:Body></s:Envelope>
|
||||
http_version:
|
||||
recorded_at: Tue, 04 Sep 2018 05:29:21 GMT
|
||||
recorded_with: VCR 4.0.0
|
Loading…
Reference in a new issue