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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/dependabot.yml +29 -0
  3. data/.github/workflows/push.yml +1 -1
  4. data/.github/workflows/test.yml +3 -3
  5. data/.rubocop.yml +136 -26
  6. data/README.md +1 -1
  7. data/api-tester.gemspec +3 -3
  8. data/lib/api-tester/config.rb +1 -2
  9. data/lib/api-tester/definition/boundary_case.rb +1 -3
  10. data/lib/api-tester/definition/contract.rb +4 -4
  11. data/lib/api-tester/definition/endpoint.rb +35 -17
  12. data/lib/api-tester/definition/fields/array_field.rb +8 -4
  13. data/lib/api-tester/definition/fields/boolean_field.rb +9 -2
  14. data/lib/api-tester/definition/fields/email_field.rb +16 -2
  15. data/lib/api-tester/definition/fields/enum_field.rb +8 -4
  16. data/lib/api-tester/definition/fields/field.rb +12 -6
  17. data/lib/api-tester/definition/fields/number_field.rb +13 -2
  18. data/lib/api-tester/definition/fields/object_field.rb +8 -4
  19. data/lib/api-tester/definition/fields/plain_array_field.rb +2 -2
  20. data/lib/api-tester/definition/method.rb +1 -3
  21. data/lib/api-tester/definition/request.rb +7 -10
  22. data/lib/api-tester/definition/response.rb +11 -4
  23. data/lib/api-tester/method_case_test.rb +8 -8
  24. data/lib/api-tester/modules/benchmark_module.rb +35 -0
  25. data/lib/api-tester/modules/extra_verbs.rb +7 -1
  26. data/lib/api-tester/modules/good_case.rb +1 -1
  27. data/lib/api-tester/modules/good_variations.rb +69 -0
  28. data/lib/api-tester/modules/injection_module.rb +12 -6
  29. data/lib/api-tester/modules/missing_resource.rb +64 -0
  30. data/lib/api-tester/modules/server_information.rb +1 -2
  31. data/lib/api-tester/modules/typo.rb +3 -1
  32. data/lib/api-tester/modules/unused_fields.rb +1 -1
  33. data/lib/api-tester/reporter/api_report.rb +3 -2
  34. data/lib/api-tester/reporter/missing_field_report.rb +1 -4
  35. data/lib/api-tester/reporter/report.rb +2 -6
  36. data/lib/api-tester/reporter/response_time_report.rb +24 -0
  37. data/lib/api-tester/reporter/status_code_report.rb +1 -2
  38. data/lib/api-tester/test_helper.rb +2 -0
  39. data/lib/api-tester/util/response_evaluator.rb +37 -22
  40. data/lib/api-tester/util/supported_verbs.rb +2 -2
  41. data/lib/api-tester/version.rb +1 -1
  42. metadata +14 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2f8866f2783c0595b22817fbd6fbaaab7a77531bf55358a50f6e0b3a62fec22a
4
- data.tar.gz: 7aa5c6d1d261f322a8190781b62b3bc235641a7c0eec625afb1f9a9900cb4abe
3
+ metadata.gz: 49d90cf3987edaf1eb823c6bb98fda6618ca9caf02a4475913cd9f7fd7a38c8d
4
+ data.tar.gz: d78b67dd228819bb6a7d9554206679f8b720d41df7acbaa28aef6db5c4bd2253
5
5
  SHA512:
6
- metadata.gz: 52da12901f51389ca9a4fb37d775aa8974e7514571d900fcbcfb660b6174f8251d42f6a0bb7fa9b23b3d61b01d64aa7c116c2128badf7390e2dfe106e8703ec3
7
- data.tar.gz: 8ae063b4473b4f1fb75ceb203dc569f0e8cc16b8e9963f434bd85aad1c618daecfff77caf4a93d876b7af24cf037118635351ac98bbf82af1491b012c5c5804f
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}}
@@ -9,7 +9,7 @@ jobs:
9
9
  runs-on: ubuntu-latest
10
10
 
11
11
  steps:
12
- - uses: actions/checkout@v2
12
+ - uses: actions/checkout@v3
13
13
  - name: Set up Ruby 2.6
14
14
  uses: actions/setup-ruby@v1
15
15
  with:
@@ -7,7 +7,7 @@
7
7
 
8
8
  name: Test
9
9
 
10
- on: [push, pull_request]
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@v2
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@a195098f6b1e9074390215a49c1c14e82151a289
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 [Trello Board](https://trello.com/b/R3RtsJ2A/api-tester) to see progress and where we are headed!
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.7.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', '~> 0.93.0'
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.0.2'
45
+ spec.add_runtime_dependency 'injection_vulnerability_library', '0.1.3'
46
46
  spec.add_runtime_dependency 'rest-client', '~> 2.0'
47
47
  end
@@ -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.test_helper = ApiTester::TestHelper.new
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
- temp_url.sub! "{#{param}}", test_helper.retrieve_param(param)
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 = RestClient::Request.execute(method_defaults)
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
- url = query ? "#{base_url}#{self.url}?#{query}" : "#{base_url}#{self.url}"
65
+ call_url = query ? "#{base_url}#{url}?#{query}" : "#{base_url}#{url}"
56
66
  begin
57
- response = RestClient::Request.execute(method: method.verb,
58
- url: url,
59
- payload: payload.to_json,
60
- headers: headers)
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 default_value
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.default_value
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:, default_value: true, required: false)
9
- super name: name, default_value: default_value, required: required
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
- def initialize(name:, default_value: 'test@test.com', required: false)
9
- super name: name, default_value: default_value, required: required
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:, default_value: nil, required: false)
11
- if default_value
12
- super name: name, default_value: default_value, required: required
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, default_value: acceptable_values[0], required: required
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, default_value: 'string')
8
+ def initialize(name:, required: false, has_key: true, default: 'string')
12
9
  self.name = name
13
- self.default_value = default_value
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:, default_value: 5, required: false)
9
- super name: name, default_value: default_value, required: required
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 default_value
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.default_value
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:, default_value: [], required: false)
9
- super name: name, default_value: default_value, required: required
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