api-tester 0.0.1

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 (43) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +6 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +182 -0
  8. data/Rakefile +6 -0
  9. data/api-tester.gemspec +39 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +8 -0
  12. data/lib/tester.rb +7 -0
  13. data/lib/tester/api_tester.rb +48 -0
  14. data/lib/tester/definition/boundary_case.rb +11 -0
  15. data/lib/tester/definition/endpoint.rb +22 -0
  16. data/lib/tester/definition/fields/array_field.rb +44 -0
  17. data/lib/tester/definition/fields/boolean_field.rb +18 -0
  18. data/lib/tester/definition/fields/email_field.rb +20 -0
  19. data/lib/tester/definition/fields/enum_field.rb +27 -0
  20. data/lib/tester/definition/fields/field.rb +47 -0
  21. data/lib/tester/definition/fields/number_field.rb +17 -0
  22. data/lib/tester/definition/fields/object_field.rb +42 -0
  23. data/lib/tester/definition/methods/api_get.rb +21 -0
  24. data/lib/tester/definition/methods/api_method.rb +22 -0
  25. data/lib/tester/definition/methods/api_post.rb +26 -0
  26. data/lib/tester/definition/request.rb +49 -0
  27. data/lib/tester/definition/response.rb +29 -0
  28. data/lib/tester/method_case_test.rb +67 -0
  29. data/lib/tester/modules/format.rb +26 -0
  30. data/lib/tester/modules/good_case.rb +29 -0
  31. data/lib/tester/modules/module.rb +38 -0
  32. data/lib/tester/modules/typo.rb +67 -0
  33. data/lib/tester/modules/unused_fields.rb +22 -0
  34. data/lib/tester/reporter/api_report.rb +33 -0
  35. data/lib/tester/reporter/missing_field_report.rb +23 -0
  36. data/lib/tester/reporter/missing_response_field_report.rb +19 -0
  37. data/lib/tester/reporter/report.rb +25 -0
  38. data/lib/tester/reporter/status_code_report.rb +12 -0
  39. data/lib/tester/test_helper.rb +7 -0
  40. data/lib/tester/util/response_evaluator.rb +73 -0
  41. data/lib/tester/util/supported_verbs.rb +25 -0
  42. data/lib/tester/version.rb +3 -0
  43. metadata +157 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 83ee0d9e20fbd649a77f024ef5c59374598defdb
4
+ data.tar.gz: e940bd076054a3a8fef1d64cdeac36692622dec8
5
+ SHA512:
6
+ metadata.gz: 1917a357518a7d848197699e4ef169b409668954f3054c1259835a5424270d815cceae899c841d994eccf8fdb28dfe48d2e7c6955fad2649d4a1c994e933a81b
7
+ data.tar.gz: f791aa624ebbcd765073765a3949714ad851ffac7a8fd3f50df5bd66ad5c0f82588fca83e86bdd0c446d3f5bd793c5c7b8dd5f08a38ef53aaa1382f975238864
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ .idea
11
+ *.swp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 2.2.1
5
+
6
+ before_install: gem install bundler -v 1.13.6
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in api-tester.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 araneforseti
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,182 @@
1
+ # Api::Tester
2
+ [![Build Status](https://travis-ci.org/araneforseti/api-tester.svg?branch=master)](https://travis-ci.org/araneforseti/api-tester)
3
+
4
+ Work in Progress! Use at own risk, definitely not ready
5
+ for prime time!
6
+
7
+ This gem is intended to enable easy creation of tests for
8
+ RESTful API services when given a contract.
9
+
10
+ Check out [API Tester Example](https://github.com/araneforseti/example_api-tester) for an example in action
11
+
12
+ # Feature Plan
13
+ ## Under Development
14
+ Check out our [Trello Board](https://trello.com/b/R3RtsJ2A/api-tester) to see progress and where we are headed!
15
+ Feel free to leave feedback through github's issue tracker
16
+
17
+ - Format module:
18
+ - Checks syntax problems with the request and
19
+ ensuring a consistent response
20
+ - Typo module:
21
+ - Tests incorrect verbs and simulates typos in the url
22
+ - Good Case (name pending) module:
23
+ - Checks expected good requests will work
24
+ (eg, number field should accept integers
25
+ between 1 - 100)
26
+ - Unused Fields module:
27
+ - A module which runs after all the others and reports on any response fields which were never returned
28
+
29
+ ## Intended Features Before "Release"
30
+
31
+ - Other Param Testing
32
+ - Path
33
+ - Query
34
+ - Headers
35
+ - Endpoint Testing
36
+ - Unused Response Fields
37
+ - Invalid method names
38
+ - Invalid method types
39
+ - Documentation
40
+ - Generate Swagger-compliant documentation
41
+ - Generate definitions from Swagger documentation
42
+
43
+ ## What is this not intended for?
44
+
45
+ - Logic testing (eg, if X is between A and B, then Y is
46
+ required)
47
+
48
+ # Usage
49
+ ## Installation
50
+
51
+ Add this line to your application's Gemfile:
52
+
53
+ ```ruby
54
+ gem 'api-tester'
55
+ ```
56
+
57
+ And then execute:
58
+
59
+ $ bundle
60
+
61
+ Or install it yourself as:
62
+
63
+ $ gem install api-tester
64
+
65
+ ## Usage in Code
66
+
67
+ Warning: This gem is still in alpha stage. Use at own risk
68
+ understanding the contract will change until the first
69
+ stable release
70
+
71
+ Define your endpoints using
72
+ ```ruby
73
+ endpoint = Endpoint.new "Some name which is currently unused"
74
+ ```
75
+
76
+ Define methods on endpoints
77
+
78
+ ```ruby
79
+ get_method = ApiGet.new "http://yourbase.com/api/method"
80
+ ```
81
+ Note: Currently only GET and POST have been created, but
82
+ you can make your own so long as it has `call` and `verb` methods
83
+ which will execute the method given parameters
84
+
85
+ Define fields used by the method (both Request and Response)
86
+ ```ruby
87
+ request = Request.new.add_field(Field.new "fieldName")
88
+ ```
89
+ Note: Similar to methods, you can create your own fields.
90
+ They need to repond to:
91
+ ```ruby
92
+ field.has_subfields?
93
+ values_array = field.negative_boundary_values
94
+ ```
95
+
96
+ Put them together and call go and off you go!
97
+ ```ruby
98
+ request = Request.new.add_field(Field.new "fieldName")
99
+ expected_response = Response.new(200).add_field(Field.new "fieldName")
100
+ get_method = ApiGet.new "http://yourbase.com/api/method"
101
+ get_method.request = request
102
+ get_method.expected_response = expected_response
103
+ endpoint = Endpoint.new "Unused Name Sorry"
104
+ endpoint.add_method get_method
105
+ tester = ApiTester.new(endpoint).with_module(Format.new)
106
+ expect(tester.go).to be true
107
+
108
+ ```
109
+
110
+ ## Dependencies
111
+
112
+ If your API has some setup which needs to happen before or after each call for a particular endpoint, you can use the TestHelper interface:
113
+
114
+ ```ruby
115
+ class InfoCreator < TestHelper
116
+ def before
117
+ puts "This code runs before every call"
118
+ end
119
+
120
+ def after
121
+ puts "This code runs after every call"
122
+ end
123
+ end
124
+
125
+ tester = ApiTester.new(endpoint)
126
+ tester.test_helper = InfoCreator.new
127
+ expect(tester.go).to be true
128
+ ```
129
+
130
+ # Modules
131
+ ## Boundary
132
+ This module will test out various edge cases and
133
+ ensure error handling is consistent
134
+
135
+ ## Good Case
136
+ This module ensures your 'default request' works
137
+ appropriately
138
+
139
+ ## Typo
140
+ This module checks for common integration issues when an
141
+ API is first being worked against such as urls which don't
142
+ exist and HTTP Verb against a url which does not support it
143
+
144
+ ## Unused Fields
145
+ If any response fields are not returned during tests run
146
+ by previous modules, this will fail with a report
147
+ detailing unreturned response fields. When using this
148
+ module, it is recommended the good case module is also
149
+ used.
150
+
151
+ # Reporting
152
+ Right now the default reporting mechanism prints out to
153
+ the console all the issues which were found. You can
154
+ create your own reporting class (so long as it responds
155
+ to the same methods) or just extend the current one and
156
+ override the print method. Then set the tester's report
157
+ tool:
158
+ ```ruby
159
+ tester.with_reporter(new_reporter)
160
+ ```
161
+
162
+ # Development
163
+
164
+ After checking out the repo, run `bin/setup` to install
165
+ dependencies. Then, run `rake spec` to run the tests.
166
+ You can also run `bin/console` for an interactive prompt
167
+ that will allow you to experiment.
168
+
169
+ To install this gem onto your local machine,
170
+ run `bundle exec rake install`.
171
+
172
+ ## Contributing
173
+
174
+ Bug reports and pull requests are welcome on GitHub at
175
+ https://github.com/araneforseti/api-tester.
176
+
177
+
178
+ # License
179
+
180
+ The gem is available as open source under the terms
181
+ of the [MIT License](http://opensource.org/licenses/MIT).
182
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,39 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'tester/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "api-tester"
8
+ spec.version = Tester::VERSION
9
+ spec.authors = ["arane"]
10
+ spec.email = ["arane9@gmail.com"]
11
+
12
+ spec.summary = %q{Tool to help test APIs}
13
+ spec.description = %q{Tool to test APIs which will eventually do boundary testing and other sorts of testing automatically given a contract}
14
+ spec.homepage = "https://github.com/araneforseti/api-tester"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org/'
21
+ else
22
+ raise "RubyGems 2.0 or newer is required to protect against " \
23
+ "public gem pushes."
24
+ end
25
+
26
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
27
+ f.match(%r{^(test|spec|features)/})
28
+ end
29
+ spec.bindir = "exe"
30
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
31
+ spec.require_paths = ["lib"]
32
+
33
+ spec.add_development_dependency "bundler", "~> 1.13"
34
+ spec.add_development_dependency "rake", "~> 10.0"
35
+ spec.add_development_dependency "rspec", "~> 3.0"
36
+ spec.add_development_dependency "webmock"
37
+
38
+ spec.add_runtime_dependency "rest-client"
39
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "api/tester"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/tester.rb ADDED
@@ -0,0 +1,7 @@
1
+ require "tester/version"
2
+ require 'rest-client'
3
+ require 'json'
4
+
5
+ module Tester
6
+
7
+ end
@@ -0,0 +1,48 @@
1
+ require "tester/modules/format"
2
+ require 'tester/modules/good_case'
3
+ require 'tester/modules/unused_fields'
4
+ require 'tester/modules/typo'
5
+ require 'rest-client'
6
+ require 'json'
7
+
8
+ class ApiTester
9
+ attr_accessor :report
10
+ attr_accessor :modules
11
+ attr_accessor :definition
12
+ attr_accessor :test_helper
13
+
14
+ def initialize(definition)
15
+ self.report = ApiReport.new
16
+ self.modules = []
17
+ self.definition = definition
18
+ self.test_helper = TestHelper.new
19
+ end
20
+
21
+ def with_module(new_module)
22
+ self.modules << new_module
23
+ self
24
+ end
25
+
26
+ def with_reporter(reporter)
27
+ self.report = reporter
28
+ self
29
+ end
30
+
31
+ def with_default_modules
32
+ self.modules << Format.new
33
+ self.modules << GoodCase.new
34
+ self.modules << Typo.new
35
+ self.modules << UnusedFields.new
36
+ self
37
+ end
38
+
39
+ def go
40
+ self.modules.sort_by{ |mod| mod.order }.each do |mod|
41
+ mod.test_helper = self.test_helper
42
+ mod.go self.definition, self.report
43
+ end
44
+
45
+ self.report.print
46
+ self.report.reports.size == 0
47
+ end
48
+ end
@@ -0,0 +1,11 @@
1
+ class BoundaryCase
2
+ attr_accessor :payload
3
+ attr_accessor :headers
4
+ attr_accessor :description
5
+
6
+ def initialize description, payload, headers
7
+ self.description = description
8
+ self.payload = payload
9
+ self.headers = headers
10
+ end
11
+ end
@@ -0,0 +1,22 @@
1
+ require 'tester/definition/response'
2
+
3
+ class Endpoint
4
+ attr_accessor :methods
5
+ attr_accessor :name
6
+ attr_accessor :bad_request_response
7
+ attr_accessor :not_allowed_response
8
+ attr_accessor :not_found_response
9
+
10
+ def initialize name
11
+ self.name = name
12
+ self.methods = []
13
+ self.bad_request_response = Response.new 400
14
+ self.not_allowed_response = Response.new 415
15
+ self.not_found_response = Response.new 404
16
+ end
17
+
18
+ def add_method(new_method)
19
+ self.methods << new_method
20
+ self
21
+ end
22
+ end
@@ -0,0 +1,44 @@
1
+ require 'tester/definition/fields/field'
2
+
3
+ class ArrayField < Field
4
+ attr_accessor :fields
5
+
6
+ def initialize name
7
+ super(name)
8
+ self.fields = []
9
+ end
10
+
11
+ def with_field(newField)
12
+ self.fields << newField
13
+ self
14
+ end
15
+
16
+ def has_subfields?
17
+ true
18
+ end
19
+
20
+ def default_value
21
+ if self.fields.size == 0
22
+ return []
23
+ end
24
+
25
+ obj = Hash.new
26
+ self.fields.each do |field|
27
+ obj[field.name] = field.default_value
28
+ end
29
+ [obj]
30
+ end
31
+
32
+ def negative_boundary_values
33
+ super +
34
+ [
35
+ "string",
36
+ 123,
37
+ 0,
38
+ 1,
39
+ true,
40
+ false,
41
+ {}
42
+ ]
43
+ end
44
+ end