api-tester 1.1.1 → 1.1.2
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.
- checksums.yaml +4 -4
- data/.github/workflows/dependabot.yml +29 -0
- data/.github/workflows/push.yml +1 -1
- data/.github/workflows/test.yml +3 -3
- data/.rubocop.yml +136 -26
- data/README.md +1 -1
- data/api-tester.gemspec +3 -3
- data/lib/api-tester/config.rb +1 -2
- data/lib/api-tester/definition/boundary_case.rb +1 -3
- data/lib/api-tester/definition/contract.rb +4 -4
- data/lib/api-tester/definition/endpoint.rb +35 -17
- data/lib/api-tester/definition/fields/array_field.rb +8 -4
- data/lib/api-tester/definition/fields/boolean_field.rb +9 -2
- data/lib/api-tester/definition/fields/email_field.rb +16 -2
- data/lib/api-tester/definition/fields/enum_field.rb +8 -4
- data/lib/api-tester/definition/fields/field.rb +12 -6
- data/lib/api-tester/definition/fields/number_field.rb +13 -2
- data/lib/api-tester/definition/fields/object_field.rb +8 -4
- data/lib/api-tester/definition/fields/plain_array_field.rb +2 -2
- data/lib/api-tester/definition/method.rb +1 -3
- data/lib/api-tester/definition/request.rb +7 -10
- data/lib/api-tester/definition/response.rb +11 -4
- data/lib/api-tester/method_case_test.rb +8 -8
- data/lib/api-tester/modules/benchmark_module.rb +35 -0
- data/lib/api-tester/modules/extra_verbs.rb +7 -1
- data/lib/api-tester/modules/good_case.rb +1 -1
- data/lib/api-tester/modules/good_variations.rb +69 -0
- data/lib/api-tester/modules/injection_module.rb +12 -6
- data/lib/api-tester/modules/missing_resource.rb +64 -0
- data/lib/api-tester/modules/server_information.rb +1 -2
- data/lib/api-tester/modules/typo.rb +3 -1
- data/lib/api-tester/modules/unused_fields.rb +1 -1
- data/lib/api-tester/reporter/api_report.rb +3 -2
- data/lib/api-tester/reporter/missing_field_report.rb +1 -4
- data/lib/api-tester/reporter/report.rb +2 -6
- data/lib/api-tester/reporter/response_time_report.rb +24 -0
- data/lib/api-tester/reporter/status_code_report.rb +1 -2
- data/lib/api-tester/test_helper.rb +2 -0
- data/lib/api-tester/util/response_evaluator.rb +37 -22
- data/lib/api-tester/util/supported_verbs.rb +2 -2
- data/lib/api-tester/version.rb +1 -1
- metadata +14 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49d90cf3987edaf1eb823c6bb98fda6618ca9caf02a4475913cd9f7fd7a38c8d
|
4
|
+
data.tar.gz: d78b67dd228819bb6a7d9554206679f8b720d41df7acbaa28aef6db5c4bd2253
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c65fa30cad7b220c5055991385a26b630a293fe05e4fe74841228fe3ca58516ec5f7f9745d984dbdc92a0cdf0125606bddf297187eb9a733da7d54d4eb78f1b
|
7
|
+
data.tar.gz: 9a53c3ce1e5bcd11179f718a231e966e61a536322ab096983e87caa7277223a777ef44505d8f766c50a0d196c83cd61fa0ea71f409cc5e4919f629159c3e1227
|
@@ -0,0 +1,29 @@
|
|
1
|
+
name: Dependabot Auto Merge
|
2
|
+
|
3
|
+
permissions:
|
4
|
+
pull-requests: write
|
5
|
+
contents: write
|
6
|
+
|
7
|
+
on:
|
8
|
+
pull_request:
|
9
|
+
# Allows you to run this workflow manually from the Actions tab
|
10
|
+
workflow_dispatch:
|
11
|
+
|
12
|
+
jobs:
|
13
|
+
dependabot:
|
14
|
+
# The type of runner that the job will run on
|
15
|
+
runs-on: ubuntu-latest
|
16
|
+
if: ${{ github.actor == 'dependabot[bot]' }}
|
17
|
+
# Steps represent a sequence of tasks that will be executed as part of the job
|
18
|
+
steps:
|
19
|
+
- name: Dependabot metadata
|
20
|
+
id: metadata
|
21
|
+
uses: dependabot/fetch-metadata@v1.3.3
|
22
|
+
with:
|
23
|
+
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
24
|
+
|
25
|
+
- name: Enable auto-merge for Dependabot patch update PRs
|
26
|
+
run: gh pr merge --auto --merge "$PR_URL"
|
27
|
+
env:
|
28
|
+
PR_URL: ${{github.event.pull_request.html_url}}
|
29
|
+
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
data/.github/workflows/push.yml
CHANGED
data/.github/workflows/test.yml
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
|
8
8
|
name: Test
|
9
9
|
|
10
|
-
on: [push
|
10
|
+
on: [push]
|
11
11
|
|
12
12
|
jobs:
|
13
13
|
test:
|
@@ -15,12 +15,12 @@ jobs:
|
|
15
15
|
runs-on: ubuntu-latest
|
16
16
|
|
17
17
|
steps:
|
18
|
-
- uses: actions/checkout@
|
18
|
+
- uses: actions/checkout@v3
|
19
19
|
- name: Set up Ruby
|
20
20
|
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
21
21
|
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
22
22
|
# uses: ruby/setup-ruby@v1
|
23
|
-
uses: ruby/setup-ruby@
|
23
|
+
uses: ruby/setup-ruby@08245253a76fa4d1e459b7809579c62bd9eb718a
|
24
24
|
with:
|
25
25
|
ruby-version: 2.6
|
26
26
|
- name: Install dependencies
|
data/.rubocop.yml
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
AllCops:
|
2
|
+
NewCops: enable
|
2
3
|
Exclude:
|
3
4
|
- 'Guardfile'
|
4
5
|
- '*.gemspec'
|
@@ -6,56 +7,165 @@ AllCops:
|
|
6
7
|
- '**/*.rake'
|
7
8
|
- 'bin/*'
|
8
9
|
|
10
|
+
Gemspec/RequireMFA:
|
11
|
+
Enabled: true
|
12
|
+
Gemspec/DeprecatedAttributeAssignment: # (new in 1.10)
|
13
|
+
Enabled: true
|
14
|
+
Layout/LineContinuationLeadingSpace:
|
15
|
+
Enabled: true
|
16
|
+
Layout/LineContinuationSpacing:
|
17
|
+
Enabled: true
|
18
|
+
Layout/LineEndStringConcatenationIndentation:
|
19
|
+
Enabled: true
|
20
|
+
Layout/SpaceBeforeBrackets: # (new in 1.7)
|
21
|
+
Enabled: true
|
22
|
+
Lint/AmbiguousAssignment: # (new in 1.7)
|
23
|
+
Enabled: true
|
24
|
+
Lint/DeprecatedConstants: # (new in 1.8)
|
25
|
+
Enabled: true
|
26
|
+
Lint/DuplicateBranch: # (new in 1.3)
|
27
|
+
Enabled: false
|
28
|
+
Lint/DuplicateRegexpCharacterClassElement: # (new in 1.1)
|
29
|
+
Enabled: true
|
30
|
+
Lint/EmptyBlock: # (new in 1.1)
|
31
|
+
Enabled: true
|
32
|
+
Lint/EmptyClass: # (new in 1.3)
|
33
|
+
Enabled: true
|
34
|
+
Lint/LambdaWithoutLiteralBlock: # (new in 1.8)
|
35
|
+
Enabled: true
|
36
|
+
Lint/NoReturnInBeginEndBlocks: # (new in 1.2)
|
37
|
+
Enabled: true
|
38
|
+
Lint/NumberedParameterAssignment: # (new in 1.9)
|
39
|
+
Enabled: true
|
40
|
+
Lint/OrAssignmentToConstant: # (new in 1.9)
|
41
|
+
Enabled: true
|
42
|
+
Lint/RedundantDirGlobSort: # (new in 1.8)
|
43
|
+
Enabled: true
|
44
|
+
Lint/SymbolConversion: # (new in 1.9)
|
45
|
+
Enabled: true
|
46
|
+
Lint/ToEnumArguments: # (new in 1.1)
|
47
|
+
Enabled: true
|
48
|
+
Lint/TripleQuotes: # (new in 1.9)
|
49
|
+
Enabled: true
|
50
|
+
Lint/UnexpectedBlockArity: # (new in 1.5)
|
51
|
+
Enabled: true
|
52
|
+
Lint/UnmodifiedReduceAccumulator: # (new in 1.1)
|
53
|
+
Enabled: true
|
54
|
+
Lint/AmbiguousOperatorPrecedence:
|
55
|
+
Enabled: true
|
56
|
+
Lint/AmbiguousRange:
|
57
|
+
Enabled: true
|
58
|
+
Lint/ConstantOverwrittenInRescue:
|
59
|
+
Enabled: true
|
60
|
+
Lint/EmptyInPattern: # new in 1.16
|
61
|
+
Enabled: true
|
62
|
+
Lint/IncompatibleIoSelectWithFiberScheduler: # new in 1.21
|
63
|
+
Enabled: true
|
64
|
+
Lint/NonAtomicFileOperation: # new in 1.31
|
65
|
+
Enabled: true
|
66
|
+
Lint/RefinementImportMethods: # new in 1.27
|
67
|
+
Enabled: true
|
68
|
+
Lint/RequireRelativeSelfPath: # new in 1.22
|
69
|
+
Enabled: true
|
70
|
+
Lint/UselessRuby2Keywords: # new in 1.23
|
71
|
+
Enabled: true
|
72
|
+
Lint/BooleanSymbol:
|
73
|
+
Enabled: false
|
9
74
|
Metrics/BlockLength:
|
10
75
|
Enabled: false
|
11
|
-
|
12
76
|
Metrics/MethodLength:
|
13
77
|
Enabled: false
|
14
|
-
|
15
|
-
Metrics/LineLength:
|
78
|
+
Layout/LineLength:
|
16
79
|
Enabled: false
|
17
|
-
|
18
80
|
Metrics/AbcSize:
|
19
81
|
Enabled: false
|
20
|
-
|
82
|
+
Metrics/PerceivedComplexity:
|
83
|
+
Enabled: false
|
84
|
+
Metrics/CyclomaticComplexity:
|
85
|
+
Enabled: false
|
21
86
|
Metrics/ParameterLists:
|
22
87
|
Enabled: false
|
23
|
-
|
88
|
+
Naming/BlockForwarding: # new in 1.24
|
89
|
+
Enabled: true
|
24
90
|
Naming/PredicateName:
|
25
91
|
Enabled: false
|
26
|
-
|
92
|
+
Naming/FileName:
|
93
|
+
Enabled: false
|
94
|
+
Security/CompoundHash: # new in 1.28
|
95
|
+
Enabled: true
|
96
|
+
Security/IoMethods: # new in 1.22
|
97
|
+
Enabled: true
|
98
|
+
Style/EnvHome: # new in 1.29
|
99
|
+
Enabled: true
|
100
|
+
Style/FetchEnvVar: # new in 1.28
|
101
|
+
Enabled: true
|
102
|
+
Style/FileRead: # new in 1.24
|
103
|
+
Enabled: true
|
104
|
+
Style/FileWrite: # new in 1.24
|
105
|
+
Enabled: true
|
106
|
+
Style/InPatternThen: # new in 1.16
|
107
|
+
Enabled: true
|
108
|
+
Style/MapCompactWithConditionalBlock: # new in 1.30
|
109
|
+
Enabled: true
|
110
|
+
Style/MapToHash: # new in 1.24
|
111
|
+
Enabled: true
|
112
|
+
Style/MultilineInPatternThen: # new in 1.16
|
113
|
+
Enabled: true
|
114
|
+
Style/NestedFileDirname: # new in 1.26
|
115
|
+
Enabled: true
|
116
|
+
Style/NumberedParameters: # new in 1.22
|
117
|
+
Enabled: true
|
118
|
+
Style/NumberedParametersLimit: # new in 1.22
|
119
|
+
Enabled: true
|
120
|
+
Style/ObjectThen: # new in 1.28
|
121
|
+
Enabled: true
|
122
|
+
Style/OpenStructUse: # new in 1.23
|
123
|
+
Enabled: true
|
124
|
+
Style/QuotedSymbols: # new in 1.16
|
125
|
+
Enabled: true
|
126
|
+
Style/RedundantInitialize: # new in 1.27
|
127
|
+
Enabled: false
|
128
|
+
Style/RedundantSelfAssignmentBranch: # new in 1.19
|
129
|
+
Enabled: true
|
130
|
+
Style/SelectByRegexp: # new in 1.22
|
131
|
+
Enabled: true
|
27
132
|
Style/IfUnlessModifier:
|
28
133
|
Enabled: false
|
29
|
-
|
30
134
|
Style/NilComparison:
|
31
135
|
Enabled: false
|
32
|
-
|
33
136
|
Style/NumericPredicate:
|
34
137
|
Enabled: false
|
35
|
-
|
36
138
|
Style/MultipleComparison:
|
37
139
|
Enabled: false
|
38
|
-
|
39
|
-
Metrics/PerceivedComplexity:
|
40
|
-
Enabled: false
|
41
|
-
|
42
|
-
Metrics/CyclomaticComplexity:
|
43
|
-
Enabled: false
|
44
|
-
|
45
140
|
Style/BlockDelimiters:
|
46
141
|
Enabled: false
|
47
|
-
|
48
142
|
Style/EmptyLiteral:
|
49
143
|
Enabled: false
|
50
|
-
|
51
|
-
Lint/BooleanSymbol:
|
52
|
-
Enabled: false
|
53
|
-
|
54
144
|
Style/GuardClause:
|
55
145
|
Enabled: false
|
56
|
-
|
57
|
-
Naming/FileName:
|
58
|
-
Enabled: false
|
59
|
-
|
60
146
|
Style/FrozenStringLiteralComment:
|
61
147
|
Enabled: false
|
148
|
+
Style/ArgumentsForwarding: # (new in 1.1)
|
149
|
+
Enabled: true
|
150
|
+
Style/CollectionCompact: # (new in 1.2)
|
151
|
+
Enabled: true
|
152
|
+
Style/DocumentDynamicEvalDefinition: # (new in 1.1)
|
153
|
+
Enabled: true
|
154
|
+
Style/EndlessMethod: # (new in 1.8)
|
155
|
+
Enabled: true
|
156
|
+
Style/HashConversion: # (new in 1.10)
|
157
|
+
Enabled: true
|
158
|
+
Style/HashExcept: # (new in 1.7)
|
159
|
+
Enabled: true
|
160
|
+
Style/IfWithBooleanLiteralBranches: # (new in 1.9)
|
161
|
+
Enabled: true
|
162
|
+
Style/NegatedIfElseCondition: # (new in 1.2)
|
163
|
+
Enabled: true
|
164
|
+
Style/NilLambda: # (new in 1.3)
|
165
|
+
Enabled: true
|
166
|
+
Style/RedundantArgument: # (new in 1.4)
|
167
|
+
Enabled: true
|
168
|
+
Style/StringChars: # (new in 1.12)
|
169
|
+
Enabled: true
|
170
|
+
Style/SwapValues:
|
171
|
+
Enabled: true
|
data/README.md
CHANGED
@@ -207,7 +207,7 @@ Bug reports and pull requests are welcome on [GitHub repo](https://github.com/ar
|
|
207
207
|
|
208
208
|
## Future Features Under Development
|
209
209
|
|
210
|
-
Check out our [
|
210
|
+
Check out our [Project Board](https://github.com/araneforseti/api-tester/projects/1) to see progress and where we are headed!
|
211
211
|
Feel free to leave feedback through Github's issue tracker
|
212
212
|
|
213
213
|
- Other Param Testing
|
data/api-tester.gemspec
CHANGED
@@ -31,17 +31,17 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.require_paths = ['lib']
|
32
32
|
|
33
33
|
spec.add_development_dependency 'bundler'
|
34
|
-
spec.add_development_dependency 'bundler-audit', '~>0.
|
34
|
+
spec.add_development_dependency 'bundler-audit', '~>0.9.0'
|
35
35
|
spec.add_development_dependency 'guard-rspec', '~> 4.7.3'
|
36
36
|
spec.add_development_dependency 'pry', '~> 0.11'
|
37
37
|
spec.add_development_dependency 'rake', '~> 13.0.1'
|
38
38
|
spec.add_development_dependency 'require_all', '~>3.0.0'
|
39
39
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
40
|
-
spec.add_development_dependency 'rubocop', '~>
|
40
|
+
spec.add_development_dependency 'rubocop', '~> 1.31.0'
|
41
41
|
spec.add_development_dependency 'terminal-notifier', '~> 2.0.0'
|
42
42
|
spec.add_development_dependency 'terminal-notifier-guard', '~> 1.7.0'
|
43
43
|
spec.add_development_dependency 'webmock', '~> 3.4'
|
44
44
|
|
45
|
-
spec.add_runtime_dependency 'injection_vulnerability_library', '0.
|
45
|
+
spec.add_runtime_dependency 'injection_vulnerability_library', '0.1.3'
|
46
46
|
spec.add_runtime_dependency 'rest-client', '~> 2.0'
|
47
47
|
end
|
data/lib/api-tester/config.rb
CHANGED
@@ -5,8 +5,7 @@ require 'api-tester/reporter/api_report'
|
|
5
5
|
module ApiTester
|
6
6
|
# Config class for changing how the tool operates
|
7
7
|
class Config
|
8
|
-
attr_accessor :reporter
|
9
|
-
attr_accessor :modules
|
8
|
+
attr_accessor :reporter, :modules
|
10
9
|
|
11
10
|
def initialize(reporter: ApiTester::ApiReport.new)
|
12
11
|
self.reporter = reporter
|
@@ -3,9 +3,7 @@
|
|
3
3
|
module ApiTester
|
4
4
|
# Holds data necessary for tests
|
5
5
|
class BoundaryCase
|
6
|
-
attr_accessor :payload
|
7
|
-
attr_accessor :headers
|
8
|
-
attr_accessor :description
|
6
|
+
attr_accessor :payload, :headers, :description
|
9
7
|
|
10
8
|
def initialize(description:, payload:, headers:)
|
11
9
|
self.description = description
|
@@ -3,14 +3,14 @@
|
|
3
3
|
module ApiTester
|
4
4
|
# Class to define the whole contract
|
5
5
|
class Contract
|
6
|
-
attr_accessor :name
|
7
|
-
attr_accessor :endpoints
|
8
|
-
attr_accessor :base_url
|
6
|
+
attr_accessor :name, :endpoints, :base_url, :max_time, :required_headers
|
9
7
|
|
10
|
-
def initialize(name:, base_url:)
|
8
|
+
def initialize(name:, base_url:, max_time: 500)
|
11
9
|
self.name = name
|
12
10
|
self.endpoints = []
|
13
11
|
self.base_url = base_url
|
12
|
+
self.max_time = max_time
|
13
|
+
self.required_headers = {}
|
14
14
|
end
|
15
15
|
|
16
16
|
def add_endpoint(endpoint)
|
@@ -3,36 +3,38 @@
|
|
3
3
|
require 'api-tester/definition/response'
|
4
4
|
require 'api-tester/definition/method'
|
5
5
|
require 'api-tester/test_helper'
|
6
|
+
require 'benchmark'
|
6
7
|
require 'rest-client'
|
7
8
|
require 'json'
|
9
|
+
require 'pry'
|
8
10
|
|
9
11
|
module ApiTester
|
10
12
|
# Class for defining and interacting with endpoints in a contract
|
11
13
|
class Endpoint
|
12
|
-
attr_accessor :name
|
13
|
-
attr_accessor :relative_url
|
14
|
-
attr_accessor :path_params
|
15
|
-
attr_accessor :methods
|
16
|
-
attr_accessor :test_helper
|
17
|
-
attr_accessor :bad_request_response
|
18
|
-
attr_accessor :not_allowed_response
|
19
|
-
attr_accessor :not_found_response
|
14
|
+
attr_accessor :name, :relative_url, :path_params, :methods, :test_helper, :bad_request_response, :not_allowed_response, :not_found_response, :longest_time, :required_headers
|
20
15
|
|
21
16
|
def initialize(name:, relative_url:)
|
22
17
|
self.relative_url = relative_url
|
23
18
|
self.name = name
|
24
19
|
self.methods = []
|
25
20
|
self.path_params = []
|
26
|
-
self.
|
21
|
+
self.longest_time = { time: 0 }
|
22
|
+
self.test_helper = ApiTester::TestHelper.new ''
|
27
23
|
self.bad_request_response = ApiTester::Response.new status_code: 400
|
28
24
|
self.not_allowed_response = ApiTester::Response.new status_code: 415
|
29
25
|
self.not_found_response = ApiTester::Response.new status_code: 404
|
26
|
+
self.required_headers = {}
|
27
|
+
end
|
28
|
+
|
29
|
+
def display_url
|
30
|
+
relative_url
|
30
31
|
end
|
31
32
|
|
32
33
|
def url
|
33
|
-
temp_url = relative_url
|
34
|
+
temp_url = relative_url.clone
|
34
35
|
path_params.each do |param|
|
35
|
-
|
36
|
+
value = test_helper.retrieve_param(param).to_s
|
37
|
+
temp_url = relative_url.sub "{#{param}}", value
|
36
38
|
end
|
37
39
|
temp_url
|
38
40
|
end
|
@@ -42,7 +44,15 @@ module ApiTester
|
|
42
44
|
method_defaults = methods[0].default_request
|
43
45
|
method_defaults[:url] = "#{base_url}#{url}"
|
44
46
|
begin
|
45
|
-
response =
|
47
|
+
response = nil
|
48
|
+
time = Benchmark.measure {
|
49
|
+
response = RestClient::Request.execute(method_defaults)
|
50
|
+
}
|
51
|
+
if time.real > longest_time[:time] && longest_time[:time] > 0
|
52
|
+
longest_time[:time] = time.real
|
53
|
+
longest_time[:payload] = payload.to_json
|
54
|
+
longest_time[:verb] = method.verb
|
55
|
+
end
|
46
56
|
rescue RestClient::ExceptionWithResponse => e
|
47
57
|
response = e.response
|
48
58
|
end
|
@@ -52,12 +62,20 @@ module ApiTester
|
|
52
62
|
|
53
63
|
def call(base_url:, method:, query: '', payload: {}, headers: {})
|
54
64
|
test_helper.before
|
55
|
-
|
65
|
+
call_url = query ? "#{base_url}#{url}?#{query}" : "#{base_url}#{url}"
|
56
66
|
begin
|
57
|
-
response =
|
58
|
-
|
59
|
-
|
60
|
-
|
67
|
+
response = nil
|
68
|
+
time = Benchmark.measure {
|
69
|
+
response = RestClient::Request.execute(method: method.verb,
|
70
|
+
url: call_url,
|
71
|
+
payload: payload.to_json,
|
72
|
+
headers: headers)
|
73
|
+
}
|
74
|
+
if time.real > longest_time[:time]
|
75
|
+
longest_time[:time] = time.real
|
76
|
+
longest_time[:payload] = payload.to_json
|
77
|
+
longest_time[:verb] = method.verb
|
78
|
+
end
|
61
79
|
rescue RestClient::ExceptionWithResponse => e
|
62
80
|
response = e.response
|
63
81
|
end
|
@@ -7,8 +7,8 @@ module ApiTester
|
|
7
7
|
class ArrayField < Field
|
8
8
|
attr_accessor :fields
|
9
9
|
|
10
|
-
def initialize(name:, required: false)
|
11
|
-
super name: name, required: required
|
10
|
+
def initialize(name:, required: false, has_key: true)
|
11
|
+
super name: name, required: required, has_key: has_key
|
12
12
|
self.fields = []
|
13
13
|
end
|
14
14
|
|
@@ -21,12 +21,16 @@ module ApiTester
|
|
21
21
|
true
|
22
22
|
end
|
23
23
|
|
24
|
-
def
|
24
|
+
def type
|
25
|
+
'array'
|
26
|
+
end
|
27
|
+
|
28
|
+
def default
|
25
29
|
return [] if fields.size.zero?
|
26
30
|
|
27
31
|
obj = {}
|
28
32
|
fields.each do |field|
|
29
|
-
obj[field.name] = field.
|
33
|
+
obj[field.name] = field.default
|
30
34
|
end
|
31
35
|
[obj]
|
32
36
|
end
|
@@ -5,8 +5,8 @@ require 'api-tester/definition/fields/field'
|
|
5
5
|
module ApiTester
|
6
6
|
# Class for defining booleans in contract
|
7
7
|
class BooleanField < Field
|
8
|
-
def initialize(name:,
|
9
|
-
super name: name,
|
8
|
+
def initialize(name:, default: true, required: false)
|
9
|
+
super name: name, default: default, required: required
|
10
10
|
end
|
11
11
|
|
12
12
|
def negative_boundary_values
|
@@ -19,5 +19,12 @@ module ApiTester
|
|
19
19
|
{}
|
20
20
|
]
|
21
21
|
end
|
22
|
+
|
23
|
+
def good_cases
|
24
|
+
[
|
25
|
+
true,
|
26
|
+
false
|
27
|
+
]
|
28
|
+
end
|
22
29
|
end
|
23
30
|
end
|
@@ -1,12 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'securerandom'
|
4
|
+
|
3
5
|
require 'api-tester/definition/fields/field'
|
4
6
|
|
5
7
|
module ApiTester
|
6
8
|
# Class for defining email fields in contract
|
7
9
|
class EmailField < Field
|
8
|
-
|
9
|
-
|
10
|
+
attr_accessor :randomize
|
11
|
+
|
12
|
+
def initialize(name:, default: 'test@test.com', required: false, randomize: false)
|
13
|
+
super name: name, default: default, required: required
|
14
|
+
self.randomize = randomize
|
15
|
+
end
|
16
|
+
|
17
|
+
def default
|
18
|
+
# Since many APIs have unique email checks, this allows us to generate hopefully unique emails
|
19
|
+
if randomize
|
20
|
+
"test#{SecureRandom.hex(10)}@test.com"
|
21
|
+
else
|
22
|
+
super
|
23
|
+
end
|
10
24
|
end
|
11
25
|
|
12
26
|
def negative_boundary_values
|
@@ -7,11 +7,11 @@ module ApiTester
|
|
7
7
|
class EnumField < Field
|
8
8
|
attr_accessor :acceptable_values
|
9
9
|
|
10
|
-
def initialize(name:, acceptable_values:,
|
11
|
-
if
|
12
|
-
super name: name,
|
10
|
+
def initialize(name:, acceptable_values:, default: nil, required: false)
|
11
|
+
if default
|
12
|
+
super name: name, default: default, required: required
|
13
13
|
else
|
14
|
-
super name: name,
|
14
|
+
super name: name, default: acceptable_values[0], required: required
|
15
15
|
end
|
16
16
|
|
17
17
|
self.acceptable_values = acceptable_values
|
@@ -28,5 +28,9 @@ module ApiTester
|
|
28
28
|
{}
|
29
29
|
]
|
30
30
|
end
|
31
|
+
|
32
|
+
def good_cases
|
33
|
+
acceptable_values
|
34
|
+
end
|
31
35
|
end
|
32
36
|
end
|
@@ -3,16 +3,18 @@
|
|
3
3
|
module ApiTester
|
4
4
|
# Base class for field definitions
|
5
5
|
class Field
|
6
|
-
attr_accessor :name
|
7
|
-
attr_accessor :default_value
|
8
|
-
attr_accessor :required
|
9
|
-
attr_accessor :is_seen
|
6
|
+
attr_accessor :name, :default, :required, :is_seen, :has_key
|
10
7
|
|
11
|
-
def initialize(name:, required: false,
|
8
|
+
def initialize(name:, required: false, has_key: true, default: 'string')
|
12
9
|
self.name = name
|
13
|
-
self.
|
10
|
+
self.default = default
|
14
11
|
self.required = required
|
15
12
|
self.is_seen = 0
|
13
|
+
self.has_key = has_key
|
14
|
+
end
|
15
|
+
|
16
|
+
def type
|
17
|
+
'field'
|
16
18
|
end
|
17
19
|
|
18
20
|
def is_required
|
@@ -39,6 +41,10 @@ module ApiTester
|
|
39
41
|
cases
|
40
42
|
end
|
41
43
|
|
44
|
+
def good_cases
|
45
|
+
[]
|
46
|
+
end
|
47
|
+
|
42
48
|
def seen
|
43
49
|
self.is_seen += 1
|
44
50
|
end
|
@@ -5,8 +5,8 @@ require 'api-tester/definition/fields/field'
|
|
5
5
|
module ApiTester
|
6
6
|
# Class for defining numeric fields in contracts
|
7
7
|
class NumberField < Field
|
8
|
-
def initialize(name:,
|
9
|
-
super name: name,
|
8
|
+
def initialize(name:, default: 5, required: false)
|
9
|
+
super name: name, default: default, required: required
|
10
10
|
end
|
11
11
|
|
12
12
|
def negative_boundary_values
|
@@ -18,5 +18,16 @@ module ApiTester
|
|
18
18
|
{}
|
19
19
|
]
|
20
20
|
end
|
21
|
+
|
22
|
+
def good_cases
|
23
|
+
[
|
24
|
+
-1,
|
25
|
+
0,
|
26
|
+
1,
|
27
|
+
100,
|
28
|
+
9999,
|
29
|
+
12_345_678_901_234_567_890
|
30
|
+
]
|
31
|
+
end
|
21
32
|
end
|
22
33
|
end
|
@@ -7,8 +7,8 @@ module ApiTester
|
|
7
7
|
class ObjectField < Field
|
8
8
|
attr_accessor :fields
|
9
9
|
|
10
|
-
def initialize(name:, required: false)
|
11
|
-
super name: name, required: required
|
10
|
+
def initialize(name:, required: false, has_key: true)
|
11
|
+
super name: name, required: required, has_key: has_key
|
12
12
|
self.fields = []
|
13
13
|
end
|
14
14
|
|
@@ -21,11 +21,15 @@ module ApiTester
|
|
21
21
|
true
|
22
22
|
end
|
23
23
|
|
24
|
-
def
|
24
|
+
def type
|
25
|
+
'object'
|
26
|
+
end
|
27
|
+
|
28
|
+
def default
|
25
29
|
obj = {}
|
26
30
|
|
27
31
|
fields.each do |field|
|
28
|
-
obj[field.name] = field.
|
32
|
+
obj[field.name] = field.default
|
29
33
|
end
|
30
34
|
|
31
35
|
obj
|
@@ -5,8 +5,8 @@ require 'api-tester/definition/fields/field'
|
|
5
5
|
module ApiTester
|
6
6
|
# Class for defining plain arrays
|
7
7
|
class PlainArrayField < Field
|
8
|
-
def initialize(name:,
|
9
|
-
super name: name,
|
8
|
+
def initialize(name:, default: [], required: false)
|
9
|
+
super name: name, default: default, required: required
|
10
10
|
end
|
11
11
|
|
12
12
|
def negative_boundary_values
|
@@ -3,9 +3,7 @@
|
|
3
3
|
module ApiTester
|
4
4
|
# Class for defining methods as part of an endpoint
|
5
5
|
class Method
|
6
|
-
attr_accessor :request
|
7
|
-
attr_accessor :expected_response
|
8
|
-
attr_accessor :verb
|
6
|
+
attr_accessor :request, :expected_response, :verb
|
9
7
|
|
10
8
|
def initialize(verb:, response:, request:)
|
11
9
|
self.verb = verb
|