api-tester 0.1.0 → 1.1.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.
- checksums.yaml +5 -5
 - data/.github/dependabot.yml +15 -0
 - data/.github/workflows/push.yml +39 -0
 - data/.github/workflows/test.yml +31 -0
 - data/.rspec +1 -0
 - data/.rubocop.yml +61 -0
 - data/Gemfile +2 -0
 - data/Guardfile +70 -0
 - data/README.md +106 -74
 - data/Rakefile +8 -3
 - data/api-tester.gemspec +31 -23
 - data/changelog.txt +35 -0
 - data/lib/api-tester.rb +15 -0
 - data/lib/api-tester/config.rb +43 -0
 - data/lib/api-tester/definition/boundary_case.rb +16 -0
 - data/lib/api-tester/definition/contract.rb +20 -0
 - data/lib/api-tester/definition/endpoint.rb +84 -0
 - data/lib/api-tester/definition/fields/array_field.rb +47 -0
 - data/lib/api-tester/definition/fields/boolean_field.rb +23 -0
 - data/lib/api-tester/definition/fields/email_field.rb +25 -0
 - data/lib/api-tester/definition/fields/enum_field.rb +32 -0
 - data/lib/api-tester/definition/fields/field.rb +50 -0
 - data/lib/api-tester/definition/fields/number_field.rb +22 -0
 - data/lib/api-tester/definition/fields/object_field.rb +47 -0
 - data/lib/api-tester/definition/fields/plain_array_field.rb +25 -0
 - data/lib/api-tester/definition/method.rb +22 -0
 - data/lib/api-tester/definition/request.rb +96 -0
 - data/lib/api-tester/definition/response.rb +39 -0
 - data/lib/api-tester/method_case_test.rb +83 -0
 - data/lib/api-tester/modules/extra_verbs.rb +53 -0
 - data/lib/api-tester/modules/format.rb +47 -0
 - data/lib/api-tester/modules/good_case.rb +46 -0
 - data/lib/api-tester/modules/injection_module.rb +81 -0
 - data/lib/api-tester/modules/required_fields.rb +51 -0
 - data/lib/api-tester/modules/server_information.rb +42 -0
 - data/lib/api-tester/modules/typo.rb +70 -0
 - data/lib/api-tester/modules/unexpected_fields.rb +61 -0
 - data/lib/api-tester/modules/unused_fields.rb +31 -0
 - data/lib/api-tester/reporter/api_report.rb +47 -0
 - data/lib/api-tester/reporter/missing_field_report.rb +24 -0
 - data/lib/api-tester/reporter/report.rb +30 -0
 - data/lib/api-tester/reporter/status_code_report.rb +21 -0
 - data/lib/api-tester/test_helper.rb +12 -0
 - data/lib/api-tester/util/response_evaluator.rb +88 -0
 - data/lib/api-tester/util/supported_verbs.rb +39 -0
 - data/lib/api-tester/version.rb +5 -0
 - metadata +159 -42
 - data/.travis.yml +0 -6
 - data/lib/tester.rb +0 -7
 - data/lib/tester/api_tester.rb +0 -50
 - data/lib/tester/definition/api_contract.rb +0 -13
 - data/lib/tester/definition/api_method.rb +0 -11
 - data/lib/tester/definition/boundary_case.rb +0 -11
 - data/lib/tester/definition/endpoint.rb +0 -57
 - data/lib/tester/definition/fields/array_field.rb +0 -44
 - data/lib/tester/definition/fields/boolean_field.rb +0 -18
 - data/lib/tester/definition/fields/email_field.rb +0 -20
 - data/lib/tester/definition/fields/enum_field.rb +0 -27
 - data/lib/tester/definition/fields/field.rb +0 -47
 - data/lib/tester/definition/fields/number_field.rb +0 -17
 - data/lib/tester/definition/fields/object_field.rb +0 -42
 - data/lib/tester/definition/request.rb +0 -49
 - data/lib/tester/definition/response.rb +0 -34
 - data/lib/tester/method_case_test.rb +0 -67
 - data/lib/tester/modules/extra_verbs.rb +0 -25
 - data/lib/tester/modules/format.rb +0 -26
 - data/lib/tester/modules/good_case.rb +0 -29
 - data/lib/tester/modules/module.rb +0 -18
 - data/lib/tester/modules/typo.rb +0 -41
 - data/lib/tester/modules/unused_fields.rb +0 -22
 - data/lib/tester/reporter/api_report.rb +0 -33
 - data/lib/tester/reporter/missing_field_report.rb +0 -23
 - data/lib/tester/reporter/missing_response_field_report.rb +0 -19
 - data/lib/tester/reporter/report.rb +0 -25
 - data/lib/tester/reporter/status_code_report.rb +0 -12
 - data/lib/tester/test_helper.rb +0 -10
 - data/lib/tester/util/response_evaluator.rb +0 -73
 - data/lib/tester/util/supported_verbs.rb +0 -34
 - data/lib/tester/version.rb +0 -3
 
    
        data/Rakefile
    CHANGED
    
    | 
         @@ -1,6 +1,11 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require  
     | 
| 
       2 
     | 
    
         
            -
            require  
     | 
| 
      
 1 
     | 
    
         
            +
            require 'bundler/gem_tasks'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'rspec/core/rake_task'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'rubocop/rake_task'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            RuboCop::RakeTask.new(:rubocop) do |t|
         
     | 
| 
      
 6 
     | 
    
         
            +
              t.options = ['--display-cop-names']
         
     | 
| 
      
 7 
     | 
    
         
            +
            end
         
     | 
| 
       3 
8 
     | 
    
         | 
| 
       4 
9 
     | 
    
         
             
            RSpec::Core::RakeTask.new(:spec)
         
     | 
| 
       5 
10 
     | 
    
         | 
| 
       6 
     | 
    
         
            -
            task :default => :spec
         
     | 
| 
      
 11 
     | 
    
         
            +
            task :default => [:rubocop, :spec]
         
     | 
    
        data/api-tester.gemspec
    CHANGED
    
    | 
         @@ -1,39 +1,47 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # coding: utf-8
         
     | 
| 
       2 
2 
     | 
    
         
             
            lib = File.expand_path('../lib', __FILE__)
         
     | 
| 
       3 
3 
     | 
    
         
             
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         
     | 
| 
       4 
     | 
    
         
            -
            require 'tester/version'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'api-tester/version'
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
            Gem::Specification.new do |spec|
         
     | 
| 
       7 
     | 
    
         
            -
              spec.name          =  
     | 
| 
       8 
     | 
    
         
            -
              spec.version       =  
     | 
| 
       9 
     | 
    
         
            -
              spec.authors       = [ 
     | 
| 
       10 
     | 
    
         
            -
              spec.email         = [ 
     | 
| 
      
 7 
     | 
    
         
            +
              spec.name          = 'api-tester'
         
     | 
| 
      
 8 
     | 
    
         
            +
              spec.version       = ApiTester::VERSION
         
     | 
| 
      
 9 
     | 
    
         
            +
              spec.authors       = ['arane']
         
     | 
| 
      
 10 
     | 
    
         
            +
              spec.email         = ['arane9@gmail.com']
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
              spec.summary       =  
     | 
| 
       13 
     | 
    
         
            -
              spec.description   =  
     | 
| 
       14 
     | 
    
         
            -
              spec.homepage      =  
     | 
| 
       15 
     | 
    
         
            -
              spec.license       =  
     | 
| 
      
 12 
     | 
    
         
            +
              spec.summary       = 'Tool to help test APIs'
         
     | 
| 
      
 13 
     | 
    
         
            +
              spec.description   = '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 
16 
     | 
    
         | 
| 
       17 
17 
     | 
    
         
             
              # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
         
     | 
| 
       18 
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  
     | 
| 
       23 
     | 
    
         
            -
                   
     | 
| 
       24 
     | 
    
         
            -
              end
         
     | 
| 
      
 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 
25 
     | 
    
         | 
| 
       26 
     | 
    
         
            -
              spec.files 
     | 
| 
      
 26 
     | 
    
         
            +
              spec.files = `git ls-files -z`.split("\x0").reject do |f|
         
     | 
| 
       27 
27 
     | 
    
         
             
                f.match(%r{^(test|spec|features)/})
         
     | 
| 
       28 
28 
     | 
    
         
             
              end
         
     | 
| 
       29 
     | 
    
         
            -
              spec.bindir        =  
     | 
| 
      
 29 
     | 
    
         
            +
              spec.bindir        = 'exe'
         
     | 
| 
       30 
30 
     | 
    
         
             
              spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
         
     | 
| 
       31 
     | 
    
         
            -
              spec.require_paths = [ 
     | 
| 
      
 31 
     | 
    
         
            +
              spec.require_paths = ['lib']
         
     | 
| 
       32 
32 
     | 
    
         | 
| 
       33 
     | 
    
         
            -
              spec.add_development_dependency  
     | 
| 
       34 
     | 
    
         
            -
              spec.add_development_dependency  
     | 
| 
       35 
     | 
    
         
            -
              spec.add_development_dependency  
     | 
| 
       36 
     | 
    
         
            -
              spec.add_development_dependency  
     | 
| 
      
 33 
     | 
    
         
            +
              spec.add_development_dependency 'bundler'
         
     | 
| 
      
 34 
     | 
    
         
            +
              spec.add_development_dependency 'bundler-audit', '~>0.7.0'
         
     | 
| 
      
 35 
     | 
    
         
            +
              spec.add_development_dependency 'guard-rspec', '~> 4.7.3'
         
     | 
| 
      
 36 
     | 
    
         
            +
              spec.add_development_dependency 'pry', '~> 0.11'
         
     | 
| 
      
 37 
     | 
    
         
            +
              spec.add_development_dependency 'rake', '~> 13.0.1'
         
     | 
| 
      
 38 
     | 
    
         
            +
              spec.add_development_dependency 'require_all', '~>3.0.0'
         
     | 
| 
      
 39 
     | 
    
         
            +
              spec.add_development_dependency 'rspec', '~> 3.0'
         
     | 
| 
      
 40 
     | 
    
         
            +
              spec.add_development_dependency 'rubocop', '~> 0.93.0'
         
     | 
| 
      
 41 
     | 
    
         
            +
              spec.add_development_dependency 'terminal-notifier', '~> 2.0.0'
         
     | 
| 
      
 42 
     | 
    
         
            +
              spec.add_development_dependency 'terminal-notifier-guard', '~> 1.7.0'
         
     | 
| 
      
 43 
     | 
    
         
            +
              spec.add_development_dependency 'webmock', '~> 3.4'
         
     | 
| 
       37 
44 
     | 
    
         | 
| 
       38 
     | 
    
         
            -
              spec.add_runtime_dependency  
     | 
| 
      
 45 
     | 
    
         
            +
              spec.add_runtime_dependency 'injection_vulnerability_library', '0.0.2'
         
     | 
| 
      
 46 
     | 
    
         
            +
              spec.add_runtime_dependency 'rest-client', '~> 2.0'
         
     | 
| 
       39 
47 
     | 
    
         
             
            end
         
     | 
    
        data/changelog.txt
    CHANGED
    
    | 
         @@ -1,3 +1,38 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            2.0.0
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            - Added Required Fields module
         
     | 
| 
      
 4 
     | 
    
         
            +
            - Added Unexpected Fields module
         
     | 
| 
      
 5 
     | 
    
         
            +
            - Adding query params to definition
         
     | 
| 
      
 6 
     | 
    
         
            +
            - Moved base_url to contract
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Changed endpoints to be relative urls
         
     | 
| 
      
 8 
     | 
    
         
            +
            - Removed missing field report as it was unused
         
     | 
| 
      
 9 
     | 
    
         
            +
            - Changing everything with more than one parameter to named parameters
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            1.0.0
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            - Switching to using named variables to make future changes less breaky
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            0.3.2
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            - Fixing some issues with how config adds modules
         
     | 
| 
      
 18 
     | 
    
         
            +
            - Fixing README for same module issue as config
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            0.3.1
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            - Adding ability to change headers for request objects
         
     | 
| 
      
 23 
     | 
    
         
            +
            - Removing the reports from the sub modules and making them just return their reports
         
     | 
| 
      
 24 
     | 
    
         
            +
            - Adjusted modules to use the full contract instead of endpoints
         
     | 
| 
      
 25 
     | 
    
         
            +
            - Created module to check for server information being broadcast
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            0.3.0
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            - Making modules actually be modules
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            0.2.0
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            - Finally fixing the naming scheme
         
     | 
| 
      
 34 
     | 
    
         
            +
            - Splitting configuration into its own class
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
       1 
36 
     | 
    
         
             
            0.1.0
         
     | 
| 
       2 
37 
     | 
    
         | 
| 
       3 
38 
     | 
    
         
             
            - Moving call to endpoint for path param support
         
     | 
    
        data/lib/api-tester.rb
    ADDED
    
    | 
         @@ -0,0 +1,15 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # Tool for testing through API definitions
         
     | 
| 
      
 4 
     | 
    
         
            +
            module ApiTester
         
     | 
| 
      
 5 
     | 
    
         
            +
              def self.go(contract, config)
         
     | 
| 
      
 6 
     | 
    
         
            +
                reporter = config.reporter
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                config.modules.sort_by(&:order).each do |mod|
         
     | 
| 
      
 9 
     | 
    
         
            +
                  reporter.add_reports mod.go contract
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                reporter.print
         
     | 
| 
      
 13 
     | 
    
         
            +
                reporter.reports.size.zero?
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,43 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'api-tester/reporter/api_report'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module ApiTester
         
     | 
| 
      
 6 
     | 
    
         
            +
              # Config class for changing how the tool operates
         
     | 
| 
      
 7 
     | 
    
         
            +
              class Config
         
     | 
| 
      
 8 
     | 
    
         
            +
                attr_accessor :reporter
         
     | 
| 
      
 9 
     | 
    
         
            +
                attr_accessor :modules
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                def initialize(reporter: ApiTester::ApiReport.new)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  self.reporter = reporter
         
     | 
| 
      
 13 
     | 
    
         
            +
                  self.modules = []
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                def with_reporter(reporter)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  self.reporter = reporter
         
     | 
| 
      
 18 
     | 
    
         
            +
                  self
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                def with_module(new_module)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  modules << new_module
         
     | 
| 
      
 23 
     | 
    
         
            +
                  self
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                def with_default_modules
         
     | 
| 
      
 27 
     | 
    
         
            +
                  modules << Format
         
     | 
| 
      
 28 
     | 
    
         
            +
                  modules << GoodCase
         
     | 
| 
      
 29 
     | 
    
         
            +
                  modules << Typo
         
     | 
| 
      
 30 
     | 
    
         
            +
                  modules << UnusedFields
         
     | 
| 
      
 31 
     | 
    
         
            +
                  self
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                def with_all_modules
         
     | 
| 
      
 35 
     | 
    
         
            +
                  modules << Format
         
     | 
| 
      
 36 
     | 
    
         
            +
                  modules << ExtraVerbs
         
     | 
| 
      
 37 
     | 
    
         
            +
                  modules << GoodCase
         
     | 
| 
      
 38 
     | 
    
         
            +
                  modules << Typo
         
     | 
| 
      
 39 
     | 
    
         
            +
                  modules << UnusedFields
         
     | 
| 
      
 40 
     | 
    
         
            +
                  self
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
              end
         
     | 
| 
      
 43 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,16 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module ApiTester
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Holds data necessary for tests
         
     | 
| 
      
 5 
     | 
    
         
            +
              class BoundaryCase
         
     | 
| 
      
 6 
     | 
    
         
            +
                attr_accessor :payload
         
     | 
| 
      
 7 
     | 
    
         
            +
                attr_accessor :headers
         
     | 
| 
      
 8 
     | 
    
         
            +
                attr_accessor :description
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                def initialize(description:, payload:, headers:)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  self.description = description
         
     | 
| 
      
 12 
     | 
    
         
            +
                  self.payload = payload
         
     | 
| 
      
 13 
     | 
    
         
            +
                  self.headers = headers
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module ApiTester
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Class to define the whole contract
         
     | 
| 
      
 5 
     | 
    
         
            +
              class Contract
         
     | 
| 
      
 6 
     | 
    
         
            +
                attr_accessor :name
         
     | 
| 
      
 7 
     | 
    
         
            +
                attr_accessor :endpoints
         
     | 
| 
      
 8 
     | 
    
         
            +
                attr_accessor :base_url
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                def initialize(name:, base_url:)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  self.name = name
         
     | 
| 
      
 12 
     | 
    
         
            +
                  self.endpoints = []
         
     | 
| 
      
 13 
     | 
    
         
            +
                  self.base_url = base_url
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                def add_endpoint(endpoint)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  endpoints << endpoint
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,84 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'api-tester/definition/response'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'api-tester/definition/method'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'api-tester/test_helper'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'rest-client'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'json'
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            module ApiTester
         
     | 
| 
      
 10 
     | 
    
         
            +
              # Class for defining and interacting with endpoints in a contract
         
     | 
| 
      
 11 
     | 
    
         
            +
              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
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                def initialize(name:, relative_url:)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  self.relative_url = relative_url
         
     | 
| 
      
 23 
     | 
    
         
            +
                  self.name = name
         
     | 
| 
      
 24 
     | 
    
         
            +
                  self.methods = []
         
     | 
| 
      
 25 
     | 
    
         
            +
                  self.path_params = []
         
     | 
| 
      
 26 
     | 
    
         
            +
                  self.test_helper = ApiTester::TestHelper.new
         
     | 
| 
      
 27 
     | 
    
         
            +
                  self.bad_request_response = ApiTester::Response.new status_code: 400
         
     | 
| 
      
 28 
     | 
    
         
            +
                  self.not_allowed_response = ApiTester::Response.new status_code: 415
         
     | 
| 
      
 29 
     | 
    
         
            +
                  self.not_found_response = ApiTester::Response.new status_code: 404
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                def url
         
     | 
| 
      
 33 
     | 
    
         
            +
                  temp_url = relative_url
         
     | 
| 
      
 34 
     | 
    
         
            +
                  path_params.each do |param|
         
     | 
| 
      
 35 
     | 
    
         
            +
                    temp_url.sub! "{#{param}}", test_helper.retrieve_param(param)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
                  temp_url
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                def default_call(base_url)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  test_helper.before
         
     | 
| 
      
 42 
     | 
    
         
            +
                  method_defaults = methods[0].default_request
         
     | 
| 
      
 43 
     | 
    
         
            +
                  method_defaults[:url] = "#{base_url}#{url}"
         
     | 
| 
      
 44 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 45 
     | 
    
         
            +
                    response = RestClient::Request.execute(method_defaults)
         
     | 
| 
      
 46 
     | 
    
         
            +
                  rescue RestClient::ExceptionWithResponse => e
         
     | 
| 
      
 47 
     | 
    
         
            +
                    response = e.response
         
     | 
| 
      
 48 
     | 
    
         
            +
                  end
         
     | 
| 
      
 49 
     | 
    
         
            +
                  test_helper.after
         
     | 
| 
      
 50 
     | 
    
         
            +
                  response
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                def call(base_url:, method:, query: '', payload: {}, headers: {})
         
     | 
| 
      
 54 
     | 
    
         
            +
                  test_helper.before
         
     | 
| 
      
 55 
     | 
    
         
            +
                  url = query ? "#{base_url}#{self.url}?#{query}" : "#{base_url}#{self.url}"
         
     | 
| 
      
 56 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 57 
     | 
    
         
            +
                    response = RestClient::Request.execute(method: method.verb,
         
     | 
| 
      
 58 
     | 
    
         
            +
                                                           url: url,
         
     | 
| 
      
 59 
     | 
    
         
            +
                                                           payload: payload.to_json,
         
     | 
| 
      
 60 
     | 
    
         
            +
                                                           headers: headers)
         
     | 
| 
      
 61 
     | 
    
         
            +
                  rescue RestClient::ExceptionWithResponse => e
         
     | 
| 
      
 62 
     | 
    
         
            +
                    response = e.response
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
                  test_helper.after
         
     | 
| 
      
 65 
     | 
    
         
            +
                  response
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                def add_method(verb:, response:, request: Request.new)
         
     | 
| 
      
 69 
     | 
    
         
            +
                  methods << ApiTester::Method.new(verb: verb,
         
     | 
| 
      
 70 
     | 
    
         
            +
                                                   response: response,
         
     | 
| 
      
 71 
     | 
    
         
            +
                                                   request: request)
         
     | 
| 
      
 72 
     | 
    
         
            +
                  self
         
     | 
| 
      
 73 
     | 
    
         
            +
                end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                def add_path_param(param)
         
     | 
| 
      
 76 
     | 
    
         
            +
                  path_params << param
         
     | 
| 
      
 77 
     | 
    
         
            +
                  self
         
     | 
| 
      
 78 
     | 
    
         
            +
                end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                def verbs
         
     | 
| 
      
 81 
     | 
    
         
            +
                  methods.map(&:verb)
         
     | 
| 
      
 82 
     | 
    
         
            +
                end
         
     | 
| 
      
 83 
     | 
    
         
            +
              end
         
     | 
| 
      
 84 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,47 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'api-tester/definition/fields/field'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module ApiTester
         
     | 
| 
      
 6 
     | 
    
         
            +
              # Class used for defining array fields
         
     | 
| 
      
 7 
     | 
    
         
            +
              class ArrayField < Field
         
     | 
| 
      
 8 
     | 
    
         
            +
                attr_accessor :fields
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                def initialize(name:, required: false)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  super name: name, required: required
         
     | 
| 
      
 12 
     | 
    
         
            +
                  self.fields = []
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                def with_field(new_field)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  fields << new_field
         
     | 
| 
      
 17 
     | 
    
         
            +
                  self
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                def subfields?
         
     | 
| 
      
 21 
     | 
    
         
            +
                  true
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                def default_value
         
     | 
| 
      
 25 
     | 
    
         
            +
                  return [] if fields.size.zero?
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  obj = {}
         
     | 
| 
      
 28 
     | 
    
         
            +
                  fields.each do |field|
         
     | 
| 
      
 29 
     | 
    
         
            +
                    obj[field.name] = field.default_value
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
                  [obj]
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                def negative_boundary_values
         
     | 
| 
      
 35 
     | 
    
         
            +
                  super +
         
     | 
| 
      
 36 
     | 
    
         
            +
                    [
         
     | 
| 
      
 37 
     | 
    
         
            +
                      'string',
         
     | 
| 
      
 38 
     | 
    
         
            +
                      123,
         
     | 
| 
      
 39 
     | 
    
         
            +
                      0,
         
     | 
| 
      
 40 
     | 
    
         
            +
                      1,
         
     | 
| 
      
 41 
     | 
    
         
            +
                      true,
         
     | 
| 
      
 42 
     | 
    
         
            +
                      false,
         
     | 
| 
      
 43 
     | 
    
         
            +
                      {}
         
     | 
| 
      
 44 
     | 
    
         
            +
                    ]
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,23 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'api-tester/definition/fields/field'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module ApiTester
         
     | 
| 
      
 6 
     | 
    
         
            +
              # Class for defining booleans in contract
         
     | 
| 
      
 7 
     | 
    
         
            +
              class BooleanField < Field
         
     | 
| 
      
 8 
     | 
    
         
            +
                def initialize(name:, default_value: true, required: false)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  super name: name, default_value: default_value, required: required
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def negative_boundary_values
         
     | 
| 
      
 13 
     | 
    
         
            +
                  super +
         
     | 
| 
      
 14 
     | 
    
         
            +
                    [
         
     | 
| 
      
 15 
     | 
    
         
            +
                      'string',
         
     | 
| 
      
 16 
     | 
    
         
            +
                      123,
         
     | 
| 
      
 17 
     | 
    
         
            +
                      0,
         
     | 
| 
      
 18 
     | 
    
         
            +
                      1,
         
     | 
| 
      
 19 
     | 
    
         
            +
                      {}
         
     | 
| 
      
 20 
     | 
    
         
            +
                    ]
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,25 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'api-tester/definition/fields/field'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module ApiTester
         
     | 
| 
      
 6 
     | 
    
         
            +
              # Class for defining email fields in contract
         
     | 
| 
      
 7 
     | 
    
         
            +
              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 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def negative_boundary_values
         
     | 
| 
      
 13 
     | 
    
         
            +
                  super +
         
     | 
| 
      
 14 
     | 
    
         
            +
                    [
         
     | 
| 
      
 15 
     | 
    
         
            +
                      'string',
         
     | 
| 
      
 16 
     | 
    
         
            +
                      123,
         
     | 
| 
      
 17 
     | 
    
         
            +
                      1,
         
     | 
| 
      
 18 
     | 
    
         
            +
                      0,
         
     | 
| 
      
 19 
     | 
    
         
            +
                      true,
         
     | 
| 
      
 20 
     | 
    
         
            +
                      false,
         
     | 
| 
      
 21 
     | 
    
         
            +
                      {}
         
     | 
| 
      
 22 
     | 
    
         
            +
                    ]
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,32 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'api-tester/definition/fields/field'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module ApiTester
         
     | 
| 
      
 6 
     | 
    
         
            +
              # Class for defining enumerators
         
     | 
| 
      
 7 
     | 
    
         
            +
              class EnumField < Field
         
     | 
| 
      
 8 
     | 
    
         
            +
                attr_accessor :acceptable_values
         
     | 
| 
      
 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
         
     | 
| 
      
 13 
     | 
    
         
            +
                  else
         
     | 
| 
      
 14 
     | 
    
         
            +
                    super name: name, default_value: acceptable_values[0], required: required
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  self.acceptable_values = acceptable_values
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                def negative_boundary_values
         
     | 
| 
      
 21 
     | 
    
         
            +
                  super +
         
     | 
| 
      
 22 
     | 
    
         
            +
                    [
         
     | 
| 
      
 23 
     | 
    
         
            +
                      123,
         
     | 
| 
      
 24 
     | 
    
         
            +
                      0,
         
     | 
| 
      
 25 
     | 
    
         
            +
                      1,
         
     | 
| 
      
 26 
     | 
    
         
            +
                      true,
         
     | 
| 
      
 27 
     | 
    
         
            +
                      false,
         
     | 
| 
      
 28 
     | 
    
         
            +
                      {}
         
     | 
| 
      
 29 
     | 
    
         
            +
                    ]
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,50 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module ApiTester
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Base class for field definitions
         
     | 
| 
      
 5 
     | 
    
         
            +
              class Field
         
     | 
| 
      
 6 
     | 
    
         
            +
                attr_accessor :name
         
     | 
| 
      
 7 
     | 
    
         
            +
                attr_accessor :default_value
         
     | 
| 
      
 8 
     | 
    
         
            +
                attr_accessor :required
         
     | 
| 
      
 9 
     | 
    
         
            +
                attr_accessor :is_seen
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                def initialize(name:, required: false, default_value: 'string')
         
     | 
| 
      
 12 
     | 
    
         
            +
                  self.name = name
         
     | 
| 
      
 13 
     | 
    
         
            +
                  self.default_value = default_value
         
     | 
| 
      
 14 
     | 
    
         
            +
                  self.required = required
         
     | 
| 
      
 15 
     | 
    
         
            +
                  self.is_seen = 0
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                def is_required
         
     | 
| 
      
 19 
     | 
    
         
            +
                  self.required = true
         
     | 
| 
      
 20 
     | 
    
         
            +
                  self
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                def is_not_required
         
     | 
| 
      
 24 
     | 
    
         
            +
                  self.required = false
         
     | 
| 
      
 25 
     | 
    
         
            +
                  self
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                def subfields?
         
     | 
| 
      
 29 
     | 
    
         
            +
                  false
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                def fields
         
     | 
| 
      
 33 
     | 
    
         
            +
                  []
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                def negative_boundary_values
         
     | 
| 
      
 37 
     | 
    
         
            +
                  cases = []
         
     | 
| 
      
 38 
     | 
    
         
            +
                  cases << nil if required
         
     | 
| 
      
 39 
     | 
    
         
            +
                  cases
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                def seen
         
     | 
| 
      
 43 
     | 
    
         
            +
                  self.is_seen += 1
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                def display_class
         
     | 
| 
      
 47 
     | 
    
         
            +
                  self.class
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
            end
         
     |