leap_salesforce 0.1.12 → 0.1.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.idea/leap-salesforce.iml +2 -2
- data/ChangeLog +5 -0
- data/PITCHME.md +7 -6
- data/README.md +54 -0
- data/leap_salesforce.gemspec +2 -2
- data/lib/leap_salesforce.rb +1 -0
- data/lib/leap_salesforce/generator/default.rb +1 -1
- data/lib/leap_salesforce/soql_data/soql_global_object_data.rb +3 -3
- data/lib/leap_salesforce/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2bdee6f535909036c914ded9bf6a3e558947795a7e2368a3cf0c9ba21901b3d
|
4
|
+
data.tar.gz: 26e600cd1fab6236d251738837e19c9034e0bb2e98cbfdfa7f535c93f4899a4e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 47508644606e0aa2b11a6654e4369ad469ae783df0f2c777a981b97332508420112e5a0e3297d959903f4a296bc306b891f95ce85ea5dd2680f4c6fd8b2ba3dd
|
7
|
+
data.tar.gz: fca8cb67769917a6542bbf27fc6047f9038d0078bd05ed1aa696f3215b45b84b114f2b87e82c66a8163432a8ac6c3aeddf0270548800f3848721bc1436f513c8
|
data/.idea/leap-salesforce.iml
CHANGED
@@ -22,7 +22,7 @@
|
|
22
22
|
<orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.3, RVM: ruby-2.6.0) [gem]" level="application" />
|
23
23
|
<orderEntry type="library" scope="PROVIDED" name="domain_name (v0.5.20190701, RVM: ruby-2.6.0) [gem]" level="application" />
|
24
24
|
<orderEntry type="library" scope="PROVIDED" name="factory_bot (v5.0.2, RVM: ruby-2.6.0) [gem]" level="application" />
|
25
|
-
<orderEntry type="library" scope="PROVIDED" name="faker (
|
25
|
+
<orderEntry type="library" scope="PROVIDED" name="faker (v2.0.0, RVM: ruby-2.6.0) [gem]" level="application" />
|
26
26
|
<orderEntry type="library" scope="PROVIDED" name="gyoku (v1.3.1, RVM: ruby-2.6.0) [gem]" level="application" />
|
27
27
|
<orderEntry type="library" scope="PROVIDED" name="hashie (v3.6.0, RVM: ruby-2.6.0) [gem]" level="application" />
|
28
28
|
<orderEntry type="library" scope="PROVIDED" name="http-cookie (v1.0.3, RVM: ruby-2.6.0) [gem]" level="application" />
|
@@ -67,7 +67,7 @@
|
|
67
67
|
<orderEntry type="library" scope="PROVIDED" name="sinatra (v2.0.4, RVM: ruby-2.6.0) [gem]" level="application" />
|
68
68
|
<orderEntry type="library" scope="PROVIDED" name="sinatra-basic-auth (v0.1.0, RVM: ruby-2.6.0) [gem]" level="application" />
|
69
69
|
<orderEntry type="library" scope="PROVIDED" name="sinatra-docdsl (v0.8.6, RVM: ruby-2.6.0) [gem]" level="application" />
|
70
|
-
<orderEntry type="library" scope="PROVIDED" name="soaspec (v0.2.
|
70
|
+
<orderEntry type="library" scope="PROVIDED" name="soaspec (v0.2.29, RVM: ruby-2.6.0) [gem]" level="application" />
|
71
71
|
<orderEntry type="library" scope="PROVIDED" name="socksify (v1.7.1, RVM: ruby-2.6.0) [gem]" level="application" />
|
72
72
|
<orderEntry type="library" scope="PROVIDED" name="thor (v0.20.3, RVM: ruby-2.6.0) [gem]" level="application" />
|
73
73
|
<orderEntry type="library" scope="PROVIDED" name="thread_safe (v0.3.6, RVM: ruby-2.6.0) [gem]" level="application" />
|
data/ChangeLog
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
Version 0.1.13
|
2
|
+
* Bug Fix
|
3
|
+
* Updated 'Delete' where must_pass of true was calling 'successful?' method on wrong object
|
4
|
+
* Account for new faker syntax of 2.0
|
5
|
+
|
1
6
|
Version 0.1.12
|
2
7
|
* Enhancements
|
3
8
|
* Add contact factory to source control so it can be used to demonstrate traits and associations
|
data/PITCHME.md
CHANGED
@@ -78,12 +78,13 @@ metadata.
|
|
78
78
|
---?code=spec/integration/creating_spec.rb&lang=ruby&title=Creating entities
|
79
79
|
|
80
80
|
@[1](Declare what it is you're testing)
|
81
|
-
@[
|
82
|
-
@[
|
83
|
-
@[
|
84
|
-
@[
|
85
|
-
@[
|
86
|
-
@[9
|
81
|
+
@[3](Define what 'it' is, a the object under test must do)
|
82
|
+
@[4](Create an instance of the object class - nothing sent to Salesforce yet)
|
83
|
+
@[5-6](Set the first and last name to random names)
|
84
|
+
@[7](Create the object in Salesforce by sending request via API)
|
85
|
+
@[8](Verify creation was successful)
|
86
|
+
@[9](Verify first name set as expected)
|
87
|
+
@[17-20](Creating through Factory)
|
87
88
|
|
88
89
|
---
|
89
90
|
|
data/README.md
CHANGED
@@ -55,6 +55,9 @@ this [here](https://asciinema.org/a/259098).
|
|
55
55
|
|
56
56
|
### Understanding how things work
|
57
57
|
|
58
|
+
This section details what the most important files are, how to define test users
|
59
|
+
and how to create, read, update, and delete data.
|
60
|
+
|
58
61
|
#### Important files
|
59
62
|
|
60
63
|
To see how things fit together, look at the [structure](#structure) section below.
|
@@ -111,6 +114,57 @@ LeapSalesforce.api_user = LeapSalesforce::Users.where username: /admin/
|
|
111
114
|
LeapSalesforce.api_user = LeapSalesforce::Users.where description: /System Admin/
|
112
115
|
```
|
113
116
|
|
117
|
+
#### CRUD of data
|
118
|
+
|
119
|
+
To work data in Salesforce, an object inheriting from the `SoqlData` class is always used. The idea is
|
120
|
+
that an object in Ruby code maps to the object in Salesforce and requests and updates to this object
|
121
|
+
are reflected in Salesforce.
|
122
|
+
|
123
|
+
When the initialisation script is run, it creates such classes in a folder called `soql_data`.
|
124
|
+
|
125
|
+
Following a simple example of a class representing the 'ContentDocument' object in Salesforce. It
|
126
|
+
also requires a generated file that specifies accessors to set and retrieve information about the object.
|
127
|
+
|
128
|
+
```ruby
|
129
|
+
require_relative 'document_field_names'
|
130
|
+
# An Document object mapping to a SOQL ContentDocument
|
131
|
+
class Document < SoqlData
|
132
|
+
include Document::Fields
|
133
|
+
soql_object 'ContentDocument'
|
134
|
+
end
|
135
|
+
```
|
136
|
+
|
137
|
+
For all interactions with Salesforce the API traffic logs are recorded in a log created in the `logs`
|
138
|
+
folder of the suite.
|
139
|
+
|
140
|
+
##### Creating entities
|
141
|
+
|
142
|
+
There are several ways entities can be created. By instantiating the object with the `new` method a new
|
143
|
+
object will be created in memory but in Salesforce. Only when the `save!` method is called will an object
|
144
|
+
be created.
|
145
|
+
|
146
|
+
For example
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
@contact = Contact.new # Create an object in memory
|
150
|
+
@contact.last_name = 'Test Person' # Set the last name field of that object to 'Test Person'
|
151
|
+
@contact.save! # Calls Salesforce API to create a new object with the fields set in the object
|
152
|
+
```
|
153
|
+
|
154
|
+
The `log` for this call will look like the following:
|
155
|
+
|
156
|
+
```verilog
|
157
|
+
Leaps, [13:39:14] : Example Factory for 'Contact'
|
158
|
+
Leaps, [13:39:14] : request body: {"FirstName":"Lewis","LastName":"Gleichner"}
|
159
|
+
Leaps, [13:39:14] : RestClient.post "https://brave-otter-ttxype-dev-ed.my.salesforce.com/services/data/v45.0/sobjects/Contact", "{\"FirstName\":\"Lewis\",\"LastName\":\"Gleichner\"}", "Accept"=>"*/*", "Accept-Encoding"=>"gzip, deflate", "Authorization"=>"Bearer 00D2v000001eBDw!AREAQK_UWp9onsfZdv5ag5j70WIbwe_IG5tLJHKC1Ti0lpVZY0EsKcmpCE8bqTd7GtGx9WmN57PRpp06yhmfczK9TUR9rZx2", "Content-Length"=>"44", "Content-Type"=>"application/json", "User-Agent"=>"rest-client/2.0.2 (linux-gnu x86_64) ruby/2.6.0p0"
|
160
|
+
|
161
|
+
Leaps, [13:39:16] : # => 201 Created | application/json 71 bytes
|
162
|
+
|
163
|
+
Leaps, [13:39:16] : response:
|
164
|
+
headers: {:date=>"Thu, 01 Aug 2019 01:39:15 GMT", :strict_transport_security=>"max-age=31536002; includeSubDomains", :public_key_pins_report_only=>"pin-sha256=\"9n0izTnSRF+W4W4JTq51avSXkWhQB8duS2bxVLfzXsY=\"; pin-sha256=\"5kJvNEMw0KjrCAu7eXY5HZdvyCS13BbA0VJG1RSP91w=\"; pin-sha256=\"njN4rRG+22dNXAi+yb8e3UMypgzPUPHlv4+foULwl1g=\"; max-age=86400; includeSubDomains; report-uri=\"https://a.forcesslreports.com/hpkp-report/00D2v000001eBDwm\";", :expect_ct=>"max-age=86400; report-uri=\"https://a.forcesslreports.com/Expect-CT-report/00D2v000001eBDwm\";", :x_content_type_options=>"nosniff", :x_xss_protection=>"1; mode=block", :x_robots_tag=>"none", :cache_control=>"no-cache,must-revalidate,max-age=0,no-store,private", :set_cookie=>["BrowserId=DOR6nshpQC659waq6EKS3A;Path=/;Domain=.salesforce.com;Expires=Mon, 30-Sep-2019 01:39:15 GMT;Max-Age=5184000"], :expires=>"Thu, 01 Jan 1970 00:00:00 GMT", :sforce_limit_info=>"api-usage=331/15000", :location=>"/services/data/v45.0/sobjects/Contact/0032v00002qU3hvAAC", :content_type=>"application/json;charset=UTF-8", :vary=>"Accept-Encoding", :content_encoding=>"gzip", :transfer_encoding=>"chunked"}
|
165
|
+
body: {"id":"0032v00002qU3hvAAC","success":true,"errors":[]}
|
166
|
+
```
|
167
|
+
|
114
168
|
## Structure
|
115
169
|
|
116
170
|
Following is the general structure of test automation suite that uses this approach. Details may vary depending on the
|
data/leap_salesforce.gemspec
CHANGED
@@ -33,12 +33,12 @@ It reads the Metadata from Salesforce and creates the foundation for API tests.'
|
|
33
33
|
spec.add_dependency 'activerecord'
|
34
34
|
spec.add_dependency 'colorize'
|
35
35
|
spec.add_dependency 'factory_bot'
|
36
|
-
spec.add_dependency 'faker'
|
36
|
+
spec.add_dependency 'faker', '>= 2.0'
|
37
37
|
spec.add_dependency 'humanize'
|
38
38
|
spec.add_dependency 'rake'
|
39
39
|
spec.add_dependency 'require_all'
|
40
40
|
spec.add_dependency 'rubocop'
|
41
41
|
spec.add_dependency 'rubykeyword'
|
42
|
-
spec.add_dependency 'soaspec', '>= 0.2.
|
42
|
+
spec.add_dependency 'soaspec', '>= 0.2.29'
|
43
43
|
spec.add_dependency 'thor'
|
44
44
|
end
|
data/lib/leap_salesforce.rb
CHANGED
@@ -5,6 +5,7 @@ require 'leap_salesforce/version'
|
|
5
5
|
require 'soaspec'
|
6
6
|
Soaspec::OAuth2.refresh_token = :once # Save access token and reuse it
|
7
7
|
Soaspec.log_warnings = false # Log any API warnings
|
8
|
+
Soaspec::SpecLogger.progname = 'Leaps'
|
8
9
|
Soaspec::OAuth2.request_message = false
|
9
10
|
Soaspec::OAuth2.retry_limit = 1 # Retrying for OAuth token too many times results in user locked out
|
10
11
|
require 'active_support/core_ext/integer/time' # Creating time objects
|
@@ -18,7 +18,7 @@ module LeapSalesforce
|
|
18
18
|
def value_for(field, class_name)
|
19
19
|
@field = field
|
20
20
|
case field['type']
|
21
|
-
when 'string' then set("Faker::Lorem.paragraph_by_chars(#{field['length']})")
|
21
|
+
when 'string' then set("Faker::Lorem.paragraph_by_chars(number: #{field['length']})")
|
22
22
|
when 'id' then set('Best to not hard code this', use_quotes: true)
|
23
23
|
when 'boolean' then set('true')
|
24
24
|
when 'picklist' then set("#{class_name}::#{field['label'].to_class_name}.sample")
|
@@ -162,17 +162,17 @@ module SoqlGlobalObjectData
|
|
162
162
|
# Remove object from Salesforce with provided id
|
163
163
|
# @param [String] id Id of element to remove
|
164
164
|
# @param [Boolean] must_pass Whether to raise exception if call is not successful
|
165
|
-
# @return [
|
165
|
+
# @return [self] Exchange object making delete call
|
166
166
|
def delete(id, must_pass: false)
|
167
167
|
SoqlData.ids_to_delete.reject! { |table, id_to_remove| table == self && id_to_remove == id } # Remove id from list to delete
|
168
168
|
remove_dependent_records(id)
|
169
169
|
|
170
170
|
SoqlHandler.new("Delete #{id}").use
|
171
|
-
delete = new(
|
171
|
+
delete = new("SOQL Delete #{id}", method: :delete, suburl: "sobjects/#{soql_object_name}/#{id}")
|
172
172
|
delete.call
|
173
173
|
return delete unless must_pass
|
174
174
|
|
175
|
-
successful?
|
175
|
+
delete.successful?
|
176
176
|
delete
|
177
177
|
end
|
178
178
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: leap_salesforce
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- IQA
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2019-
|
12
|
+
date: 2019-08-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -115,14 +115,14 @@ dependencies:
|
|
115
115
|
requirements:
|
116
116
|
- - ">="
|
117
117
|
- !ruby/object:Gem::Version
|
118
|
-
version: '0'
|
118
|
+
version: '2.0'
|
119
119
|
type: :runtime
|
120
120
|
prerelease: false
|
121
121
|
version_requirements: !ruby/object:Gem::Requirement
|
122
122
|
requirements:
|
123
123
|
- - ">="
|
124
124
|
- !ruby/object:Gem::Version
|
125
|
-
version: '0'
|
125
|
+
version: '2.0'
|
126
126
|
- !ruby/object:Gem::Dependency
|
127
127
|
name: humanize
|
128
128
|
requirement: !ruby/object:Gem::Requirement
|
@@ -199,14 +199,14 @@ dependencies:
|
|
199
199
|
requirements:
|
200
200
|
- - ">="
|
201
201
|
- !ruby/object:Gem::Version
|
202
|
-
version: 0.2.
|
202
|
+
version: 0.2.29
|
203
203
|
type: :runtime
|
204
204
|
prerelease: false
|
205
205
|
version_requirements: !ruby/object:Gem::Requirement
|
206
206
|
requirements:
|
207
207
|
- - ">="
|
208
208
|
- !ruby/object:Gem::Version
|
209
|
-
version: 0.2.
|
209
|
+
version: 0.2.29
|
210
210
|
- !ruby/object:Gem::Dependency
|
211
211
|
name: thor
|
212
212
|
requirement: !ruby/object:Gem::Requirement
|