rhoconnect-adapters 1.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/CHANGELOG +4 -0
- data/Gemfile +18 -0
- data/README.md +239 -0
- data/Rakefile +31 -0
- data/bin/rhoconnect-adapters +35 -0
- data/generators/crm/templates/application/application.rb +34 -0
- data/generators/crm/templates/source/source_adapter.rb +10 -0
- data/generators/crm/templates/source/source_spec.rb +25 -0
- data/generators/crm/templates/spec/spec_helper.rb +64 -0
- data/generators/crm/vendor/ms_dynamics/adapter.rb +301 -0
- data/generators/crm/vendor/ms_dynamics/application.rb +56 -0
- data/generators/crm/vendor/ms_dynamics/lib/crm_metadata_service.rb +43 -0
- data/generators/crm/vendor/ms_dynamics/lib/crm_service.rb +141 -0
- data/generators/crm/vendor/ms_dynamics/lib/discovery_service.rb +51 -0
- data/generators/crm/vendor/ms_dynamics/lib/wlid_service.rb +159 -0
- data/generators/crm/vendor/ms_dynamics/ms_dynamics.rb +45 -0
- data/generators/crm/vendor/ms_dynamics/settings/Account.yml +46 -0
- data/generators/crm/vendor/ms_dynamics/settings/Contact.yml +40 -0
- data/generators/crm/vendor/ms_dynamics/settings/GenericObject.yml +18 -0
- data/generators/crm/vendor/ms_dynamics/settings/Lead.yml +53 -0
- data/generators/crm/vendor/ms_dynamics/settings/Opportunity.yml +41 -0
- data/generators/crm/vendor/ms_dynamics/settings/settings.yml +9 -0
- data/generators/crm/vendor/ms_dynamics/spec/application_spec.rb +23 -0
- data/generators/crm/vendor/ms_dynamics/spec/sources/account_spec.rb +49 -0
- data/generators/crm/vendor/ms_dynamics/spec/sources/contact_spec.rb +49 -0
- data/generators/crm/vendor/ms_dynamics/spec/sources/lead_spec.rb +49 -0
- data/generators/crm/vendor/ms_dynamics/spec/sources/opportunity_spec.rb +62 -0
- data/generators/crm/vendor/ms_dynamics/spec/spec_helper.rb +78 -0
- data/generators/crm/vendor/ms_dynamics/spec_data/Account.yml +6 -0
- data/generators/crm/vendor/ms_dynamics/spec_data/Contact.yml +7 -0
- data/generators/crm/vendor/ms_dynamics/spec_data/GenericObject.yml +3 -0
- data/generators/crm/vendor/ms_dynamics/spec_data/Lead.yml +12 -0
- data/generators/crm/vendor/ms_dynamics/spec_data/Opportunity.yml +6 -0
- data/generators/crm/vendor/ms_dynamics/templates.rb +57 -0
- data/generators/crm/vendor/oracle_on_demand/adapter.rb +421 -0
- data/generators/crm/vendor/oracle_on_demand/application.rb +64 -0
- data/generators/crm/vendor/oracle_on_demand/settings/Account.yml +91 -0
- data/generators/crm/vendor/oracle_on_demand/settings/Contact.yml +54 -0
- data/generators/crm/vendor/oracle_on_demand/settings/GenericObject.yml +21 -0
- data/generators/crm/vendor/oracle_on_demand/settings/Lead.yml +72 -0
- data/generators/crm/vendor/oracle_on_demand/settings/Opportunity.yml +69 -0
- data/generators/crm/vendor/oracle_on_demand/settings/settings.yml +8 -0
- data/generators/crm/vendor/oracle_on_demand/spec/application_spec.rb +14 -0
- data/generators/crm/vendor/oracle_on_demand/spec/sources/account_spec.rb +50 -0
- data/generators/crm/vendor/oracle_on_demand/spec/sources/contact_spec.rb +50 -0
- data/generators/crm/vendor/oracle_on_demand/spec/sources/lead_spec.rb +51 -0
- data/generators/crm/vendor/oracle_on_demand/spec/sources/opportunity_spec.rb +51 -0
- data/generators/crm/vendor/oracle_on_demand/spec_data/Account.yml +8 -0
- data/generators/crm/vendor/oracle_on_demand/spec_data/Contact.yml +8 -0
- data/generators/crm/vendor/oracle_on_demand/spec_data/GenericObject.yml +4 -0
- data/generators/crm/vendor/oracle_on_demand/spec_data/Lead.yml +14 -0
- data/generators/crm/vendor/oracle_on_demand/spec_data/Opportunity.yml +6 -0
- data/generators/crm/vendor/oracle_on_demand/templates.rb +52 -0
- data/generators/crm/vendor/salesforce/adapter.rb +315 -0
- data/generators/crm/vendor/salesforce/application.rb +80 -0
- data/generators/crm/vendor/salesforce/settings/Account.yml +53 -0
- data/generators/crm/vendor/salesforce/settings/Contact.yml +61 -0
- data/generators/crm/vendor/salesforce/settings/GenericObject.yml +13 -0
- data/generators/crm/vendor/salesforce/settings/Lead.yml +73 -0
- data/generators/crm/vendor/salesforce/settings/Opportunity.yml +48 -0
- data/generators/crm/vendor/salesforce/settings/settings.yml +6 -0
- data/generators/crm/vendor/salesforce/spec/application_spec.rb +14 -0
- data/generators/crm/vendor/salesforce/spec/sources/account_spec.rb +50 -0
- data/generators/crm/vendor/salesforce/spec/sources/contact_spec.rb +50 -0
- data/generators/crm/vendor/salesforce/spec/sources/lead_spec.rb +51 -0
- data/generators/crm/vendor/salesforce/spec/sources/opportunity_spec.rb +51 -0
- data/generators/crm/vendor/salesforce/spec_data/Account.yml +14 -0
- data/generators/crm/vendor/salesforce/spec_data/Contact.yml +8 -0
- data/generators/crm/vendor/salesforce/spec_data/GenericObject.yml +3 -0
- data/generators/crm/vendor/salesforce/spec_data/Lead.yml +10 -0
- data/generators/crm/vendor/salesforce/spec_data/Opportunity.yml +10 -0
- data/generators/crm/vendor/salesforce/templates.rb +45 -0
- data/generators/crm/vendor/sugar/adapter.rb +291 -0
- data/generators/crm/vendor/sugar/application.rb +50 -0
- data/generators/crm/vendor/sugar/settings/Account.yml +49 -0
- data/generators/crm/vendor/sugar/settings/Contact.yml +62 -0
- data/generators/crm/vendor/sugar/settings/GenericObject.yml +12 -0
- data/generators/crm/vendor/sugar/settings/Lead.yml +76 -0
- data/generators/crm/vendor/sugar/settings/Opportunity.yml +49 -0
- data/generators/crm/vendor/sugar/settings/settings.yml +9 -0
- data/generators/crm/vendor/sugar/spec/application_spec.rb +25 -0
- data/generators/crm/vendor/sugar/spec/sources/account_spec.rb +53 -0
- data/generators/crm/vendor/sugar/spec/sources/contact_spec.rb +53 -0
- data/generators/crm/vendor/sugar/spec/sources/lead_spec.rb +54 -0
- data/generators/crm/vendor/sugar/spec/sources/opportunity_spec.rb +54 -0
- data/generators/crm/vendor/sugar/spec_data/Account.yml +13 -0
- data/generators/crm/vendor/sugar/spec_data/Contact.yml +8 -0
- data/generators/crm/vendor/sugar/spec_data/GenericObject.yml +3 -0
- data/generators/crm/vendor/sugar/spec_data/Lead.yml +16 -0
- data/generators/crm/vendor/sugar/spec_data/Opportunity.yml +10 -0
- data/generators/crm/vendor/sugar/sugar.rb +33 -0
- data/generators/crm/vendor/sugar/templates.rb +58 -0
- data/generators/rhoconnect-adapters.rb +217 -0
- data/lib/rhoconnect-adapters/crm/crm.rb +31 -0
- data/lib/rhoconnect-adapters/soap_service.rb +70 -0
- data/lib/rhoconnect-adapters/version.rb +3 -0
- data/lib/rhoconnect-adapters.rb +2 -0
- data/rhoconnect-adapters.gemspec +36 -0
- data/spec/apps/ms_dynamics_spec.rb +19 -0
- data/spec/apps/oracle_on_demand_spec.rb +20 -0
- data/spec/apps/salesforce_spec.rb +18 -0
- data/spec/apps/sugar_spec.rb +18 -0
- data/spec/generator/generator_spec.rb +113 -0
- data/spec/spec_helper.rb +57 -0
- metadata +288 -0
@@ -0,0 +1,159 @@
|
|
1
|
+
module RhoconnectAdapters
|
2
|
+
module CRM
|
3
|
+
module MsDynamics
|
4
|
+
class WlidService < SoapService
|
5
|
+
def self.get_ticket(user_name,password)
|
6
|
+
# device client ID
|
7
|
+
client_id = UUIDTools::UUID.random_create
|
8
|
+
# random device name
|
9
|
+
device_name = rand(10000).to_s+'12345678901234567890'
|
10
|
+
# random device password
|
11
|
+
device_password = 'random-device-password'
|
12
|
+
# authentication policy
|
13
|
+
policy = "MBI_SSL"
|
14
|
+
# open information about CRM Online
|
15
|
+
partner = "crm.dynamics.com";
|
16
|
+
# Get authorization endpoint
|
17
|
+
authorization_endpoint = self._get_authorization_endpoint
|
18
|
+
# Do the following once per machine.
|
19
|
+
# Register each machine that you need to authenticate with.
|
20
|
+
self._register_machine(device_name,device_password,client_id)
|
21
|
+
# Get device token based for the registered machine
|
22
|
+
device_token = self._get_device_token(authorization_endpoint,device_name,device_password)
|
23
|
+
# Get WLID Ticket for the user
|
24
|
+
self._get_ticket(authorization_endpoint,user_name,password,partner,policy,client_id,device_token)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
class << self
|
29
|
+
def _get_authorization_endpoint
|
30
|
+
xml = RestClient.get("https://nexus.passport.com/federationmetadata/2006-12/FederationMetaData.xml")
|
31
|
+
federation_metadata = Nokogiri::XML(xml)
|
32
|
+
federation_metadata.xpath("//fed:FederationMetadata/fed:Federation/fed:TargetServiceEndpoint/wsa:Address").text.strip
|
33
|
+
end
|
34
|
+
|
35
|
+
# Registers a machine/device with the device registration Windows Live ID service.
|
36
|
+
# Device registration is required only once per computer or device.
|
37
|
+
# The result of this request will contain the PUID (Device ID) of the device registered
|
38
|
+
# and should be saved for later use.
|
39
|
+
# device_name - The random device name to use for this registration.
|
40
|
+
# device_password - The random device password to use for this registration.
|
41
|
+
# client_id - The app GUID, a unique id for the client/application.
|
42
|
+
def _register_machine(device_name,device_password,client_id)
|
43
|
+
device_registration_request =
|
44
|
+
"<DeviceAddRequest>
|
45
|
+
<ClientInfo name=\"#{client_id}\" version=\"1.0\"/>
|
46
|
+
<Authentication>
|
47
|
+
<Membername>11#{device_name}</Membername>
|
48
|
+
<Password>#{device_password}</Password>
|
49
|
+
</Authentication>
|
50
|
+
</DeviceAddRequest>"
|
51
|
+
windows_live_device_url = "https://login.live.com/ppsecure/DeviceAddCredential.srf"
|
52
|
+
doc = send_request(windows_live_device_url,device_registration_request,nil,"application/soap+xml; charset=UTF-8")
|
53
|
+
raise "Can't register machine with Wndows Live ID" if select_node(doc,'//DeviceAddResponse/@Success').to_s.strip != 'true'
|
54
|
+
end
|
55
|
+
|
56
|
+
# Validate Windows Live ID response for any exception.
|
57
|
+
# doc - The Windows Live ID service response.
|
58
|
+
# source - An exception source.
|
59
|
+
# Raise runtime error is request is invalid
|
60
|
+
def _is_response_valid(doc,source)
|
61
|
+
if select_node(doc,'//s:Fault').size > 0
|
62
|
+
error = "Unknown error"
|
63
|
+
begin
|
64
|
+
reason = select_node_text(doc,'//s:Reason/s:Text')
|
65
|
+
details = select_node_text(doc,'//psf:text')
|
66
|
+
code = select_node_text(doc,'//psf:code')
|
67
|
+
error = "#{reason} (#{code}): #{details}"
|
68
|
+
rescue; end
|
69
|
+
begin
|
70
|
+
raise "#{self.name} error w/ #{source}: #{error}"
|
71
|
+
rescue Exception => ex
|
72
|
+
warn "#{self.name} error: " + ex.inspect.strip
|
73
|
+
ex.backtrace.each { |line| warn 'from ' + line }
|
74
|
+
raise ex
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def _compose_header(user_token_id,user,password,client_id=nil,device_token=nil)
|
80
|
+
app_info = client_id ?
|
81
|
+
"<ps:AuthInfo Id=\"PPAuthInfo\" xmlns:ps=\"http://schemas.microsoft.com/LiveID/SoapServices/v1\">
|
82
|
+
<ps:HostingApp>#{client_id}</ps:HostingApp>
|
83
|
+
</ps:AuthInfo>" : ""
|
84
|
+
binary_security_token = device_token ?
|
85
|
+
"<wsse:BinarySecurityToken ValueType=\"urn:liveid:device\">
|
86
|
+
#{device_token}
|
87
|
+
</wsse:BinarySecurityToken>" : ""
|
88
|
+
header = "
|
89
|
+
<wsa:Action s:mustUnderstand=\"1\">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</wsa:Action>
|
90
|
+
<wsa:To s:mustUnderstand=\"1\">http://Passport.NET/tb</wsa:To>
|
91
|
+
#{app_info}
|
92
|
+
<wsse:Security>
|
93
|
+
<wsse:UsernameToken wsu:Id=\"#{user_token_id}\">
|
94
|
+
<wsse:Username>#{user}</wsse:Username>
|
95
|
+
<wsse:Password>#{password}</wsse:Password>
|
96
|
+
</wsse:UsernameToken>
|
97
|
+
#{binary_security_token}
|
98
|
+
</wsse:Security>"
|
99
|
+
end
|
100
|
+
|
101
|
+
def _compose_body(address,policy=nil)
|
102
|
+
policy_reference = policy ? "<wsp:PolicyReference URI=\"#{policy}\"/>" : ""
|
103
|
+
body = "
|
104
|
+
<wst:RequestSecurityToken Id=\"RST0\">
|
105
|
+
<wst:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</wst:RequestType>
|
106
|
+
<wsp:AppliesTo>
|
107
|
+
<wsa:EndpointReference>
|
108
|
+
<wsa:Address>#{address}</wsa:Address>
|
109
|
+
</wsa:EndpointReference>
|
110
|
+
</wsp:AppliesTo>
|
111
|
+
#{policy_reference}
|
112
|
+
</wst:RequestSecurityToken>"
|
113
|
+
end
|
114
|
+
|
115
|
+
# Get a device authorization token from the Windows Live ID service.
|
116
|
+
# authorization_endpoint - Authorization endpoint
|
117
|
+
# device_name - The random device name used for this registration.
|
118
|
+
# device_password - The random device password used for this registration.
|
119
|
+
# Returns - The device token to use when retrieving a user token
|
120
|
+
def _get_device_token(authorization_endpoint,device_name,device_password)
|
121
|
+
header = _compose_header('devicesoftware',"11#{device_name}",device_password)
|
122
|
+
body = _compose_body('http://Passport.NET/tb')
|
123
|
+
message = compose_message(header,body)
|
124
|
+
# call authorization endpoint
|
125
|
+
doc = send_request(authorization_endpoint,message,nil,"application/soap+xml; charset=UTF-8")
|
126
|
+
# validate response and raise if invalid
|
127
|
+
_is_response_valid(doc,"IssueDeviceToken")
|
128
|
+
# get device token
|
129
|
+
select_node(doc,'//wst:RequestedSecurityToken/*')
|
130
|
+
end
|
131
|
+
|
132
|
+
# Gets a Windows Live ID RequestSecurityTokenResponse ticket for a specified user.
|
133
|
+
# authorization_endpoint - Authorization endpoint
|
134
|
+
# user_name - The Windows Live ID email address for the user.
|
135
|
+
# password - The Windows Live ID password for the user.
|
136
|
+
# partner - sitename, i.e. crmapp.www.local-titan.com
|
137
|
+
# policy - auth policy, i.e. MBI_SSL
|
138
|
+
# client_id - The unique id of the client/application
|
139
|
+
# device_token - The device token xml
|
140
|
+
# Returns - A string that contains the Windows Live ID ticket for
|
141
|
+
# the supplied paramters and ticket expiration date/time
|
142
|
+
def _get_ticket(authorization_endpoint,user_name,password,partner,policy,client_id,device_token)
|
143
|
+
header = _compose_header('user',user_name,password,client_id,device_token)
|
144
|
+
body = _compose_body(partner,policy)
|
145
|
+
message = compose_message(header,body)
|
146
|
+
# call authorization endpoint
|
147
|
+
doc = send_request(authorization_endpoint,message,nil,"application/soap+xml; charset=UTF-8")
|
148
|
+
# validate response and raise if invalid
|
149
|
+
_is_response_valid(doc,"IssueTicket")
|
150
|
+
# get ticket
|
151
|
+
expires = DateTime.parse(select_node_text(doc,'//wst:Lifetime/wsu:Expires'))
|
152
|
+
ticket = select_node_text(doc,'//wsse:BinarySecurityToken')
|
153
|
+
[CGI::escape(ticket),expires]
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'uuidtools'
|
3
|
+
require 'rest-client'
|
4
|
+
require 'nokogiri'
|
5
|
+
require 'date'
|
6
|
+
|
7
|
+
require 'rhoconnect-adapters/soap_service'
|
8
|
+
require 'vendor/ms_dynamics/lib/wlid_service'
|
9
|
+
require 'vendor/ms_dynamics/lib/discovery_service'
|
10
|
+
require 'vendor/ms_dynamics/lib/crm_service'
|
11
|
+
require 'vendor/ms_dynamics/lib/crm_metadata_service'
|
12
|
+
|
13
|
+
module RhoconnectAdapters
|
14
|
+
module CRM
|
15
|
+
module MsDynamics
|
16
|
+
RhoconnectAdapters::SoapService.node_namespaces.merge!({'cds' => 'http://schemas.microsoft.com/crm/2007/CrmDiscoveryService',
|
17
|
+
'wst' => 'http://schemas.xmlsoap.org/ws/2005/02/trust',
|
18
|
+
's' => 'http://www.w3.org/2003/05/soap-envelope',
|
19
|
+
'psf' => 'http://schemas.microsoft.com/Passport/SoapServices/SOAPFault',
|
20
|
+
'cws6' => 'http://schemas.microsoft.com/crm/2006/WebServices',
|
21
|
+
'cws7' => 'http://schemas.microsoft.com/crm/2007/WebServices'});
|
22
|
+
RhoconnectAdapters::SoapService.envelope_namespaces += <<-DESC
|
23
|
+
xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\"
|
24
|
+
xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\"
|
25
|
+
xmlns:wsa=\"http://www.w3.org/2005/08/addressing\"
|
26
|
+
xmlns:wst=\"http://schemas.xmlsoap.org/ws/2005/02/trust\"
|
27
|
+
DESC
|
28
|
+
|
29
|
+
class << self
|
30
|
+
def save_auth_info(username,auth_info)
|
31
|
+
Store.put_data(auth_info_key(username),"#{username}"=>auth_info)
|
32
|
+
end
|
33
|
+
|
34
|
+
def load_auth_info(username)
|
35
|
+
Store.get_data(auth_info_key(username))[username]
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
def auth_info_key(username)
|
40
|
+
"#{username}-msdynamics-auth-info"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
Query_Fields:
|
2
|
+
# This is just a sample list of fields
|
3
|
+
# that are used in Query
|
4
|
+
accountid:
|
5
|
+
Label: Id
|
6
|
+
Type: id
|
7
|
+
name:
|
8
|
+
Label: Name
|
9
|
+
Type: textinput
|
10
|
+
accountnumber:
|
11
|
+
Label: Account Number
|
12
|
+
Type: textinput
|
13
|
+
telephone1:
|
14
|
+
Label: Main Phone
|
15
|
+
Type: textinput
|
16
|
+
emailaddress1:
|
17
|
+
Label: E-mail
|
18
|
+
Type: textinput
|
19
|
+
websiteurl:
|
20
|
+
Label: Web Site
|
21
|
+
Type: textinput
|
22
|
+
accountcategorycode:
|
23
|
+
Label: Category
|
24
|
+
Type: Picklist
|
25
|
+
industrycode:
|
26
|
+
Label: Industry
|
27
|
+
Type: Picklist
|
28
|
+
numberofemployees:
|
29
|
+
Label: Number Of Employees
|
30
|
+
Type: textinput
|
31
|
+
description:
|
32
|
+
Label: Description
|
33
|
+
Type: textarea
|
34
|
+
|
35
|
+
AttributeTypePicklists:
|
36
|
+
# these Picklists define values
|
37
|
+
# for artificially constructed fields
|
38
|
+
# that are really represent some other field's type
|
39
|
+
|
40
|
+
ObjectFields:
|
41
|
+
# these are reference fields to the other objects
|
42
|
+
|
43
|
+
TitleFields:
|
44
|
+
# these fields are concatenated to show the record
|
45
|
+
# in the Index form
|
46
|
+
- name
|
@@ -0,0 +1,40 @@
|
|
1
|
+
Query_Fields:
|
2
|
+
# This is just a sample list of fields
|
3
|
+
# that are used in QueryPage
|
4
|
+
contactid:
|
5
|
+
Label: Id
|
6
|
+
Type: id
|
7
|
+
firstname:
|
8
|
+
Label: First Name
|
9
|
+
Type: textinput
|
10
|
+
lastname:
|
11
|
+
Label: Last Name
|
12
|
+
Type: textinput
|
13
|
+
jobtitle:
|
14
|
+
Label: Job Title
|
15
|
+
Type: textinput
|
16
|
+
emailaddress1:
|
17
|
+
Label: E-mail
|
18
|
+
Type: textinput
|
19
|
+
telephone1:
|
20
|
+
Label: Main Phone
|
21
|
+
Type: textinput
|
22
|
+
mobilephone:
|
23
|
+
Label: Cell Phone
|
24
|
+
Type: textinput
|
25
|
+
description:
|
26
|
+
Label: Description
|
27
|
+
Type: textarea
|
28
|
+
|
29
|
+
AttributeTypePicklists:
|
30
|
+
# these Picklists define values
|
31
|
+
# for artificially constructed fields
|
32
|
+
# that are really represent some other field's type
|
33
|
+
|
34
|
+
ObjectFields:
|
35
|
+
|
36
|
+
TitleFields:
|
37
|
+
# these fields are concatenated to show the record
|
38
|
+
# in the Index form
|
39
|
+
- lastname
|
40
|
+
- firstname
|
@@ -0,0 +1,18 @@
|
|
1
|
+
Query_Fields:
|
2
|
+
# This is just a sample list of fields
|
3
|
+
# that are used in Query request
|
4
|
+
Id:
|
5
|
+
Label: Id
|
6
|
+
Type: id
|
7
|
+
|
8
|
+
AttributeTypePicklists:
|
9
|
+
# these Picklists define values
|
10
|
+
# for artificially constructed fields
|
11
|
+
# that are really represent some other field's type
|
12
|
+
|
13
|
+
ObjectFields:
|
14
|
+
# these are reference fields to the other objects
|
15
|
+
|
16
|
+
TitleFields:
|
17
|
+
# these fields are concatenated to show the record
|
18
|
+
# in the Index form
|
@@ -0,0 +1,53 @@
|
|
1
|
+
Query_Fields:
|
2
|
+
# This is just a sample list of fields
|
3
|
+
# that are used in Query
|
4
|
+
leadid:
|
5
|
+
Label: Id
|
6
|
+
Type: id
|
7
|
+
firstname:
|
8
|
+
Label: First Name
|
9
|
+
Type: textinput
|
10
|
+
lastname:
|
11
|
+
Label: Last Name
|
12
|
+
Type: textinput
|
13
|
+
mobilephone:
|
14
|
+
Label: Cell Phone
|
15
|
+
Type: textinput
|
16
|
+
emailaddress1:
|
17
|
+
Label: E-mail
|
18
|
+
Type: textinput
|
19
|
+
companyname:
|
20
|
+
Label: Company
|
21
|
+
Type: textinput
|
22
|
+
jobtitle:
|
23
|
+
Label: Job Title
|
24
|
+
Type: textinput
|
25
|
+
estimatedvalue:
|
26
|
+
Label: Estimated Value
|
27
|
+
Type: textinput
|
28
|
+
estimatedclosedate:
|
29
|
+
Label: Estimated Close Date
|
30
|
+
Type: textinput
|
31
|
+
address1_country:
|
32
|
+
Label: Country
|
33
|
+
Type: textinput
|
34
|
+
address1_city:
|
35
|
+
Label: City
|
36
|
+
Type: textinput
|
37
|
+
address1_line1:
|
38
|
+
Label: Street Address
|
39
|
+
Type: textinput
|
40
|
+
|
41
|
+
AttributeTypePicklists:
|
42
|
+
# these Picklists define values
|
43
|
+
# for artificially constructed fields
|
44
|
+
# that are really represent some other field's type
|
45
|
+
|
46
|
+
ObjectFields:
|
47
|
+
# these are reference fields to the other objects
|
48
|
+
|
49
|
+
TitleFields:
|
50
|
+
# these fields are concatenated to show the record
|
51
|
+
# in the Index form
|
52
|
+
- lastname
|
53
|
+
- firstname
|
@@ -0,0 +1,41 @@
|
|
1
|
+
Query_Fields:
|
2
|
+
# This is just a sample list of fields
|
3
|
+
# that are used in Query
|
4
|
+
opportunityid:
|
5
|
+
Label: Id
|
6
|
+
Type: id
|
7
|
+
name:
|
8
|
+
Label: Name
|
9
|
+
Type: textinput
|
10
|
+
description:
|
11
|
+
Label: Description
|
12
|
+
Type: textarea
|
13
|
+
estimatedvalue:
|
14
|
+
Label: Estimated Value
|
15
|
+
Type: textinput
|
16
|
+
closeprobability:
|
17
|
+
Label: Probability
|
18
|
+
Type: textinput
|
19
|
+
customerid:
|
20
|
+
Label: Customer
|
21
|
+
Type: textinput
|
22
|
+
customerid_attrtype:
|
23
|
+
Label: Customer Type
|
24
|
+
Type: Picklist
|
25
|
+
|
26
|
+
AttributeTypePicklists:
|
27
|
+
# these Picklists define values
|
28
|
+
# for artificially constructed fields
|
29
|
+
# that are really represent some other field's type
|
30
|
+
customerid_attrtype:
|
31
|
+
- account
|
32
|
+
- contact
|
33
|
+
|
34
|
+
ObjectFields:
|
35
|
+
# these are reference fields to the other objects
|
36
|
+
|
37
|
+
TitleFields:
|
38
|
+
# these fields are concatenated to show the record
|
39
|
+
# in the Index form
|
40
|
+
- name
|
41
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'spec_helper')
|
2
|
+
|
3
|
+
describe "Application" do
|
4
|
+
it_should_behave_like "SpecHelper" do
|
5
|
+
def should_be_between(t,start,stop)
|
6
|
+
dt = DateTime.parse(t)
|
7
|
+
dt.should > DateTime.parse(start.to_s)
|
8
|
+
dt.should <= DateTime.parse(stop.to_s)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should authenticate" do
|
12
|
+
auth_info = RhoconnectAdapters::CRM::MsDynamics.load_auth_info(@test_user)
|
13
|
+
now = DateTime.now
|
14
|
+
should_be_between(auth_info['wlid_expires'],now,(now+(60 * 60 * 24)))
|
15
|
+
should_be_between(auth_info['crm_ticket_expires'],now,(now+(60 * 60 * 24)))
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should not authenticate with wrong credentials" do
|
19
|
+
Application.should_receive(:warn).once.with('Can\'t authenticate user wrong_user: #<RuntimeError: RhoconnectAdapters::CRM::MsDynamics::WlidService error w/ IssueTicket: Authentication Failure (0x80041034): The specified member name is either invalid or empty. >')
|
20
|
+
Application.authenticate('wrong_user','wrong_password',nil).should be_false
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'..','spec_helper')
|
2
|
+
|
3
|
+
describe "Account" do
|
4
|
+
it_should_behave_like "SpecHelper" do
|
5
|
+
before(:each) do
|
6
|
+
sample_data_file = File.join(File.dirname(__FILE__),'..','..','vendor','ms_dynamics','spec_data','Account.yml')
|
7
|
+
@sample_data = YAML.load_file(sample_data_file)['Account'] if sample_data_file and File.exist?(sample_data_file)
|
8
|
+
setup_test_for Account,@test_user
|
9
|
+
end
|
10
|
+
|
11
|
+
before(:each) do
|
12
|
+
@ss.adapter.login
|
13
|
+
end
|
14
|
+
|
15
|
+
after(:each) do
|
16
|
+
@ss.adapter.logoff
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should process Account query" do
|
20
|
+
result = test_query
|
21
|
+
puts result.length.inspect
|
22
|
+
query_errors.should == {}
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should process Account create" do
|
26
|
+
create_hash = @sample_data
|
27
|
+
result = test_create(create_hash)
|
28
|
+
puts result.inspect
|
29
|
+
create_hash['accountid'] = result
|
30
|
+
TestHelpers.created_records = { result => create_hash }
|
31
|
+
create_errors.should == {}
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should process Account update" do
|
35
|
+
TestHelpers.created_records.each do |key,value|
|
36
|
+
value['name'] = "Sample Update #{key.to_s}"
|
37
|
+
end
|
38
|
+
result = test_update(TestHelpers.created_records)
|
39
|
+
puts result.inspect
|
40
|
+
update_errors.should == {}
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should process Account delete" do
|
44
|
+
result = test_delete(TestHelpers.created_records)
|
45
|
+
puts result.inspect
|
46
|
+
delete_errors.should == {}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'..','spec_helper')
|
2
|
+
|
3
|
+
describe "Contact" do
|
4
|
+
it_should_behave_like "SpecHelper" do
|
5
|
+
before(:each) do
|
6
|
+
sample_data_file = File.join(File.dirname(__FILE__),'..','..','vendor','ms_dynamics','spec_data','Contact.yml')
|
7
|
+
@sample_data = YAML.load_file(sample_data_file)['Contact'] if sample_data_file and File.exist?(sample_data_file)
|
8
|
+
setup_test_for Contact,@test_user
|
9
|
+
end
|
10
|
+
|
11
|
+
before(:each) do
|
12
|
+
@ss.adapter.login
|
13
|
+
end
|
14
|
+
|
15
|
+
after(:each) do
|
16
|
+
@ss.adapter.logoff
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should process Contact query" do
|
20
|
+
result = test_query
|
21
|
+
puts result.length.inspect
|
22
|
+
query_errors.should == {}
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should process Contact create" do
|
26
|
+
create_hash = @sample_data
|
27
|
+
result = test_create(create_hash)
|
28
|
+
puts result.inspect
|
29
|
+
create_hash['contactid'] = result
|
30
|
+
TestHelpers.created_records = { result => create_hash }
|
31
|
+
create_errors.should == {}
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should process Contact update" do
|
35
|
+
TestHelpers.created_records.each do |key,value|
|
36
|
+
value['name'] = "Sample Update #{key.to_s}"
|
37
|
+
end
|
38
|
+
result = test_update(TestHelpers.created_records)
|
39
|
+
puts result.inspect
|
40
|
+
update_errors.should == {}
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should process Contact delete" do
|
44
|
+
result = test_delete(TestHelpers.created_records)
|
45
|
+
puts result.inspect
|
46
|
+
delete_errors.should == {}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'..','spec_helper')
|
2
|
+
|
3
|
+
describe "Lead" do
|
4
|
+
it_should_behave_like "SpecHelper" do
|
5
|
+
before(:each) do
|
6
|
+
sample_data_file = File.join(File.dirname(__FILE__),'..','..','vendor','ms_dynamics','spec_data','Lead.yml')
|
7
|
+
@sample_data = YAML.load_file(sample_data_file)['Lead'] if sample_data_file and File.exist?(sample_data_file)
|
8
|
+
setup_test_for Lead,@test_user
|
9
|
+
end
|
10
|
+
|
11
|
+
before(:each) do
|
12
|
+
@ss.adapter.login
|
13
|
+
end
|
14
|
+
|
15
|
+
after(:each) do
|
16
|
+
@ss.adapter.logoff
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should process Lead query" do
|
20
|
+
result = test_query
|
21
|
+
puts result.length.inspect
|
22
|
+
query_errors.should == {}
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should process Lead create" do
|
26
|
+
create_hash = @sample_data
|
27
|
+
result = test_create(create_hash)
|
28
|
+
puts result.inspect
|
29
|
+
create_hash['leadid'] = result
|
30
|
+
TestHelpers.created_records = { result => create_hash }
|
31
|
+
create_errors.should == {}
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should process Lead update" do
|
35
|
+
TestHelpers.created_records.each do |key,value|
|
36
|
+
value['name'] = "Sample Update #{key.to_s}"
|
37
|
+
end
|
38
|
+
result = test_update(TestHelpers.created_records)
|
39
|
+
puts result.inspect
|
40
|
+
update_errors.should == {}
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should process Lead delete" do
|
44
|
+
result = test_delete(TestHelpers.created_records)
|
45
|
+
puts result.inspect
|
46
|
+
delete_errors.should == {}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'..','spec_helper')
|
2
|
+
|
3
|
+
describe "Opportunity" do
|
4
|
+
it_should_behave_like "SpecHelper" do
|
5
|
+
before(:all) do
|
6
|
+
sample_data_file = File.join(File.dirname(__FILE__),'..','..','vendor','ms_dynamics','spec_data','Opportunity.yml')
|
7
|
+
@sample_data = YAML.load_file(sample_data_file)['Opportunity'] if sample_data_file and File.exist?(sample_data_file)
|
8
|
+
end
|
9
|
+
|
10
|
+
before(:each) do
|
11
|
+
setup_test_for Opportunity,@test_user
|
12
|
+
end
|
13
|
+
|
14
|
+
before(:each) do
|
15
|
+
@ss.adapter.login
|
16
|
+
end
|
17
|
+
|
18
|
+
after(:each) do
|
19
|
+
@ss.adapter.logoff
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should process Opportunity query" do
|
23
|
+
result = test_query
|
24
|
+
puts result.length.inspect
|
25
|
+
query_errors.should == {}
|
26
|
+
|
27
|
+
# Opportunity cannot be created without a valid
|
28
|
+
# customerid (which is either a Contact or Account)
|
29
|
+
# so, we are using some already existing one
|
30
|
+
# for subsequent create/update/delete specs
|
31
|
+
result.each do |key, value|
|
32
|
+
@sample_data['customerid'] = value['customerid']
|
33
|
+
@sample_data['customerid_attrtype'] = value['customerid_attrtype']
|
34
|
+
break
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should process Opportunity create" do
|
39
|
+
create_hash = @sample_data
|
40
|
+
result = test_create(create_hash)
|
41
|
+
puts result.inspect
|
42
|
+
create_hash['opportunityid'] = result
|
43
|
+
TestHelpers.created_records = { result => create_hash }
|
44
|
+
create_errors.should == {}
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should process Opportunity update" do
|
48
|
+
TestHelpers.created_records.each do |key,value|
|
49
|
+
value['name'] = "Sample Update #{key.to_s}"
|
50
|
+
end
|
51
|
+
result = test_update(TestHelpers.created_records)
|
52
|
+
puts result.inspect
|
53
|
+
update_errors.should == {}
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should process Opportunity delete" do
|
57
|
+
result = test_delete(TestHelpers.created_records)
|
58
|
+
puts result.inspect
|
59
|
+
delete_errors.should == {}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|