westfieldlabs/apivore

View on GitHub
lib/apivore/rspec_matchers.rb

Summary

Maintainability
A
0 mins
Test Coverage
require 'rspec/expectations'
require 'net/http'

module Apivore
  module RspecMatchers
    extend RSpec::Matchers::DSL
    matcher :be_consistent_with_swagger_definitions do |master_swagger_url, current_service|

      attr_reader :actual, :expected

      define_method :cleaned_definitions do |definitions, current_service|
        definitions.each do |key, definition_fields|
          # We ignore definitions that are owned exclusively by the current_service
          if [current_service] == definition_fields['x-services']
            definitions[key] = nil
          else
            # 'x-services' is added by api.westfield.io when aggregating swagger docs
            # Individual services will not have a 'x-services' property so we need to remove it to allow the comparison to pass
            definitions[key] = definition_fields.except 'x-services'
          end
        end.select{ |_, value| !value.nil? }
      end

      define_method :fetch_master_swagger do
        res =
          if master_swagger_url.starts_with? 'http'
            Net::HTTP.get_response(URI(master_swagger_url))
          else
            Net::HTTP.get_response(master_swagger_url, "/swagger.json")
          end

        unless res.is_a? Net::HTTPSuccess
          message = "Master swagger at #{master_swagger_url} not accessible\n"
          fail (message + res.body)
        end
        JSON.parse(res.body)
      end

      define_method :master_swagger do
        @master_swagger ||= fetch_master_swagger
      end

      match do |swagger_checker|
        our_swagger = swagger_checker.swagger
        master_definitions = cleaned_definitions(master_swagger["definitions"], current_service)
        our_definitions = our_swagger["definitions"]
        @actual = our_definitions.slice(*master_definitions.keys)
        @expected = master_definitions.slice(*our_definitions.keys)
        @actual == @expected
      end

      diffable
    end
  end
end