api-tester 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
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