rhoconnect-adapters 1.0.0.beta1

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.
Files changed (106) hide show
  1. data/.gitignore +4 -0
  2. data/CHANGELOG +4 -0
  3. data/Gemfile +18 -0
  4. data/README.md +239 -0
  5. data/Rakefile +31 -0
  6. data/bin/rhoconnect-adapters +35 -0
  7. data/generators/crm/templates/application/application.rb +34 -0
  8. data/generators/crm/templates/source/source_adapter.rb +10 -0
  9. data/generators/crm/templates/source/source_spec.rb +25 -0
  10. data/generators/crm/templates/spec/spec_helper.rb +64 -0
  11. data/generators/crm/vendor/ms_dynamics/adapter.rb +301 -0
  12. data/generators/crm/vendor/ms_dynamics/application.rb +56 -0
  13. data/generators/crm/vendor/ms_dynamics/lib/crm_metadata_service.rb +43 -0
  14. data/generators/crm/vendor/ms_dynamics/lib/crm_service.rb +141 -0
  15. data/generators/crm/vendor/ms_dynamics/lib/discovery_service.rb +51 -0
  16. data/generators/crm/vendor/ms_dynamics/lib/wlid_service.rb +159 -0
  17. data/generators/crm/vendor/ms_dynamics/ms_dynamics.rb +45 -0
  18. data/generators/crm/vendor/ms_dynamics/settings/Account.yml +46 -0
  19. data/generators/crm/vendor/ms_dynamics/settings/Contact.yml +40 -0
  20. data/generators/crm/vendor/ms_dynamics/settings/GenericObject.yml +18 -0
  21. data/generators/crm/vendor/ms_dynamics/settings/Lead.yml +53 -0
  22. data/generators/crm/vendor/ms_dynamics/settings/Opportunity.yml +41 -0
  23. data/generators/crm/vendor/ms_dynamics/settings/settings.yml +9 -0
  24. data/generators/crm/vendor/ms_dynamics/spec/application_spec.rb +23 -0
  25. data/generators/crm/vendor/ms_dynamics/spec/sources/account_spec.rb +49 -0
  26. data/generators/crm/vendor/ms_dynamics/spec/sources/contact_spec.rb +49 -0
  27. data/generators/crm/vendor/ms_dynamics/spec/sources/lead_spec.rb +49 -0
  28. data/generators/crm/vendor/ms_dynamics/spec/sources/opportunity_spec.rb +62 -0
  29. data/generators/crm/vendor/ms_dynamics/spec/spec_helper.rb +78 -0
  30. data/generators/crm/vendor/ms_dynamics/spec_data/Account.yml +6 -0
  31. data/generators/crm/vendor/ms_dynamics/spec_data/Contact.yml +7 -0
  32. data/generators/crm/vendor/ms_dynamics/spec_data/GenericObject.yml +3 -0
  33. data/generators/crm/vendor/ms_dynamics/spec_data/Lead.yml +12 -0
  34. data/generators/crm/vendor/ms_dynamics/spec_data/Opportunity.yml +6 -0
  35. data/generators/crm/vendor/ms_dynamics/templates.rb +57 -0
  36. data/generators/crm/vendor/oracle_on_demand/adapter.rb +421 -0
  37. data/generators/crm/vendor/oracle_on_demand/application.rb +64 -0
  38. data/generators/crm/vendor/oracle_on_demand/settings/Account.yml +91 -0
  39. data/generators/crm/vendor/oracle_on_demand/settings/Contact.yml +54 -0
  40. data/generators/crm/vendor/oracle_on_demand/settings/GenericObject.yml +21 -0
  41. data/generators/crm/vendor/oracle_on_demand/settings/Lead.yml +72 -0
  42. data/generators/crm/vendor/oracle_on_demand/settings/Opportunity.yml +69 -0
  43. data/generators/crm/vendor/oracle_on_demand/settings/settings.yml +8 -0
  44. data/generators/crm/vendor/oracle_on_demand/spec/application_spec.rb +14 -0
  45. data/generators/crm/vendor/oracle_on_demand/spec/sources/account_spec.rb +50 -0
  46. data/generators/crm/vendor/oracle_on_demand/spec/sources/contact_spec.rb +50 -0
  47. data/generators/crm/vendor/oracle_on_demand/spec/sources/lead_spec.rb +51 -0
  48. data/generators/crm/vendor/oracle_on_demand/spec/sources/opportunity_spec.rb +51 -0
  49. data/generators/crm/vendor/oracle_on_demand/spec_data/Account.yml +8 -0
  50. data/generators/crm/vendor/oracle_on_demand/spec_data/Contact.yml +8 -0
  51. data/generators/crm/vendor/oracle_on_demand/spec_data/GenericObject.yml +4 -0
  52. data/generators/crm/vendor/oracle_on_demand/spec_data/Lead.yml +14 -0
  53. data/generators/crm/vendor/oracle_on_demand/spec_data/Opportunity.yml +6 -0
  54. data/generators/crm/vendor/oracle_on_demand/templates.rb +52 -0
  55. data/generators/crm/vendor/salesforce/adapter.rb +315 -0
  56. data/generators/crm/vendor/salesforce/application.rb +80 -0
  57. data/generators/crm/vendor/salesforce/settings/Account.yml +53 -0
  58. data/generators/crm/vendor/salesforce/settings/Contact.yml +61 -0
  59. data/generators/crm/vendor/salesforce/settings/GenericObject.yml +13 -0
  60. data/generators/crm/vendor/salesforce/settings/Lead.yml +73 -0
  61. data/generators/crm/vendor/salesforce/settings/Opportunity.yml +48 -0
  62. data/generators/crm/vendor/salesforce/settings/settings.yml +6 -0
  63. data/generators/crm/vendor/salesforce/spec/application_spec.rb +14 -0
  64. data/generators/crm/vendor/salesforce/spec/sources/account_spec.rb +50 -0
  65. data/generators/crm/vendor/salesforce/spec/sources/contact_spec.rb +50 -0
  66. data/generators/crm/vendor/salesforce/spec/sources/lead_spec.rb +51 -0
  67. data/generators/crm/vendor/salesforce/spec/sources/opportunity_spec.rb +51 -0
  68. data/generators/crm/vendor/salesforce/spec_data/Account.yml +14 -0
  69. data/generators/crm/vendor/salesforce/spec_data/Contact.yml +8 -0
  70. data/generators/crm/vendor/salesforce/spec_data/GenericObject.yml +3 -0
  71. data/generators/crm/vendor/salesforce/spec_data/Lead.yml +10 -0
  72. data/generators/crm/vendor/salesforce/spec_data/Opportunity.yml +10 -0
  73. data/generators/crm/vendor/salesforce/templates.rb +45 -0
  74. data/generators/crm/vendor/sugar/adapter.rb +291 -0
  75. data/generators/crm/vendor/sugar/application.rb +50 -0
  76. data/generators/crm/vendor/sugar/settings/Account.yml +49 -0
  77. data/generators/crm/vendor/sugar/settings/Contact.yml +62 -0
  78. data/generators/crm/vendor/sugar/settings/GenericObject.yml +12 -0
  79. data/generators/crm/vendor/sugar/settings/Lead.yml +76 -0
  80. data/generators/crm/vendor/sugar/settings/Opportunity.yml +49 -0
  81. data/generators/crm/vendor/sugar/settings/settings.yml +9 -0
  82. data/generators/crm/vendor/sugar/spec/application_spec.rb +25 -0
  83. data/generators/crm/vendor/sugar/spec/sources/account_spec.rb +53 -0
  84. data/generators/crm/vendor/sugar/spec/sources/contact_spec.rb +53 -0
  85. data/generators/crm/vendor/sugar/spec/sources/lead_spec.rb +54 -0
  86. data/generators/crm/vendor/sugar/spec/sources/opportunity_spec.rb +54 -0
  87. data/generators/crm/vendor/sugar/spec_data/Account.yml +13 -0
  88. data/generators/crm/vendor/sugar/spec_data/Contact.yml +8 -0
  89. data/generators/crm/vendor/sugar/spec_data/GenericObject.yml +3 -0
  90. data/generators/crm/vendor/sugar/spec_data/Lead.yml +16 -0
  91. data/generators/crm/vendor/sugar/spec_data/Opportunity.yml +10 -0
  92. data/generators/crm/vendor/sugar/sugar.rb +33 -0
  93. data/generators/crm/vendor/sugar/templates.rb +58 -0
  94. data/generators/rhoconnect-adapters.rb +217 -0
  95. data/lib/rhoconnect-adapters/crm/crm.rb +31 -0
  96. data/lib/rhoconnect-adapters/soap_service.rb +70 -0
  97. data/lib/rhoconnect-adapters/version.rb +3 -0
  98. data/lib/rhoconnect-adapters.rb +2 -0
  99. data/rhoconnect-adapters.gemspec +36 -0
  100. data/spec/apps/ms_dynamics_spec.rb +19 -0
  101. data/spec/apps/oracle_on_demand_spec.rb +20 -0
  102. data/spec/apps/salesforce_spec.rb +18 -0
  103. data/spec/apps/sugar_spec.rb +18 -0
  104. data/spec/generator/generator_spec.rb +113 -0
  105. data/spec/spec_helper.rb +57 -0
  106. 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,9 @@
1
+ :test:
2
+ :msdynamics_ticket_url: rhomobileinc.crm.dynamics.com
3
+ :production:
4
+ :msdynamics_ticket_url: rhomobileinc.crm.dynamics.com
5
+ :development:
6
+ :msdynamics_ticket_url: rhomobileinc.crm.dynamics.com
7
+
8
+
9
+
@@ -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.&#13;>')
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