Class: LWS::Stubbing

Inherits:
Object
  • Object
show all
Includes:
WebMock::API
Defined in:
lib/lws/stubbing.rb

Overview

The LWS API stubbing class

This class regulates request stubbing based on a tree of fixtures. It can be used for testing an application that uses this library.

These fixtures are defined in files that should have the following form:

app_name:
  /model/1:
    default:
      id: 1
      attr: value
    test:
      id: 1
      attr: other_value

When initialized, for all apps, for all paths, the default stub is loaded if it exists.

Instance Method Summary collapse

Constructor Details

#initialize(stubs_dir) ⇒ void

Creates a new request stubbing object.

Also stubs requests for all apps for all paths, if a default stub exists.

Parameters:

  • stubs_dir (Pathname, String)

    path to the directory with the fixtures.

Raises:



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/lws/stubbing.rb', line 48

def initialize(stubs_dir)
  # Set up WebMock
  WebMock.enable!
  @stubs = {}

  # Load the fixtures
  unless File.directory? stubs_dir
    raise LWS::Errors::ConfigError,
      "not a valid stubs directory: #{stubs_dir}"
  end
  @fixtures = {}
  Dir["#{stubs_dir}/**/*.yml"].each do |yml_file|
    yml = File.open(yml_file) do |f|
      YAML.safe_load(f, filename: yml_file, aliases: true)
    end
    @fixtures.deep_merge! yml
  end

  # Set request stubs for the default fixtures
  @fixtures.each do |app_name, entries|
    entries.each do |path, fixtures|
      fixtures.each do |fixture_name, fixture|
        if fixture_name == "default"
          replace(:get, app_name, path, fixture_name)
          replace(:delete, app_name, path, fixture_name)
          replace(:put, app_name, path, fixture_name)
          replace(:patch, app_name, path, fixture_name)
          post_uri = Pathname.new(path).parent.to_s
          if @fixtures.dig(app_name.to_s, post_uri, "post_default")
            replace(:post, app_name, post_uri, "post_default")
          end
        end
      end
    end
  end
end

Instance Method Details

#disable!void

This method returns an undefined value.

Disables all request stubbing.

This should be used when the stubbing is not used anymore.



89
90
91
# File 'lib/lws/stubbing.rb', line 89

def disable!
  WebMock.disable!
end

#remove(method, app_name, path) ⇒ void

This method returns an undefined value.

Removes a request stub for the given HTTP method, app name and path.

Parameters:

  • method (Symbol)

    the HTTP method (:get, :put, etc.)

  • app_name (Symbol)

    the app name (see SUPPORTED_APPS)

  • path (String)

    the path part of the request URI

Raises:



145
146
147
148
149
150
151
# File 'lib/lws/stubbing.rb', line 145

def remove(method, app_name, path)
  request_stub = @stubs.delete([method, app_name, path])
  unless request_stub
    raise LWS::Errors::StubError, "no such request stub"
  end
  remove_request_stub request_stub
end

#replace(method, app_name, path, fixture_name = :default, http_status = 200) ⇒ void

Note:

For the HTTP method :delete, the response status is set to 204.

This method returns an undefined value.

Replace a request stub for the given HTTP method, app name, path by the fixture with the given name.

Parameters:

  • method (Symbol)

    the HTTP method (:get, :put, etc.)

  • app_name (Symbol)

    the app name (see LWS::SUPPORTED_APPS)

  • path (String)

    the path part of the request URI

  • fixture_name (Symbol, nil) (defaults to: :default)

    the name of the fixture to use as stub response body (or nil for an empty fixture)

  • http_status (Integer) (defaults to: 200)

    the HTTP status code to use

Raises:



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/lws/stubbing.rb', line 107

def replace(method, app_name, path, fixture_name = :default, http_status = 200)
  fixture = if fixture_name
              @fixtures.dig(app_name.to_s, path, fixture_name.to_s)
            else
              {}
            end
  unless fixture
    raise LWS::Errors::StubError,
      "fixture #{fixture_name} not found (app: #{app_name}, URI: #{path})"
  end
  app_module = LWS.app_module(app_name)
  app_endpoint_uri = app_module.api.url_prefix.dup
  app_endpoint_uri.path = path
  full_uri = "%s://%s:%s%s" % [app_endpoint_uri.scheme,
                               app_endpoint_uri.host,
                               app_endpoint_uri.port,
                               app_endpoint_uri.path]
  full_uri += "?#{app_endpoint_uri.query}" if app_endpoint_uri.query
  full_uri += "##{app_endpoint_uri.fragment}" if app_endpoint_uri.fragment

  @stubs[[method, app_name.to_sym, path]] =
    if method == :delete
      stub_request(method, full_uri)
        .to_return(body: MultiJson.dump(fixture), status: 204)
    else
      stub_request(method, full_uri)
        .to_return(body: MultiJson.dump(fixture), status: http_status)
    end
end