api-tester 0.0.1

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