-
-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
555 additions
and
203 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
require_relative 'middleware_helpers' | ||
|
||
module CypressOnRails | ||
module Vcr | ||
# Middleware to handle vcr with insert/eject endpoints | ||
class InsertEjectMiddleware | ||
include MiddlewareHelpers | ||
|
||
def initialize(app, vcr = nil) | ||
@app = app | ||
@vcr = vcr | ||
@first_call = false | ||
end | ||
|
||
def call(env) | ||
request = Rack::Request.new(env) | ||
if request.path.start_with?('/__e2e__/vcr/insert') | ||
configuration.tagged_logged { handle_insert(request) } | ||
elsif request.path.start_with?('/__e2e__/vcr/eject') | ||
configuration.tagged_logged { handle_eject } | ||
else | ||
do_first_call unless @first_call | ||
@app.call(env) | ||
end | ||
end | ||
|
||
private | ||
|
||
def handle_insert(req) | ||
WebMock.enable! if defined?(WebMock) | ||
vcr.turn_on! | ||
body = parse_request_body(req) | ||
logger.info "vcr insert cassette: #{body}" | ||
cassette_name, options = extract_cassette_info(body) | ||
vcr.insert_cassette(cassette_name, options) | ||
[201, { 'Content-Type' => 'application/json' }, [{ 'message': 'OK' }.to_json]] | ||
rescue JSON::ParserError => e | ||
[400, { 'Content-Type' => 'application/json' }, [{ 'message': e.message }.to_json]] | ||
rescue LoadError, ArgumentError => e | ||
[500, { 'Content-Type' => 'application/json' }, [{ 'message': e.message }.to_json]] | ||
end | ||
|
||
def parse_request_body(req) | ||
JSON.parse(req.body.read) | ||
end | ||
|
||
def extract_cassette_info(body) | ||
cassette_name = body[0] | ||
options = (body[1] || {}).symbolize_keys | ||
options[:record] = options[:record].to_sym if options[:record] | ||
options[:match_requests_on] = options[:match_requests_on].map(&:to_sym) if options[:match_requests_on] | ||
options[:serialize_with] = options[:serialize_with].to_sym if options[:serialize_with] | ||
options[:persist_with] = options[:persist_with].to_sym if options[:persist_with] | ||
[cassette_name, options] | ||
end | ||
|
||
def handle_eject | ||
logger.info 'vcr eject cassette' | ||
vcr.eject_cassette | ||
do_first_call | ||
[201, { 'Content-Type' => 'application/json' }, [{ 'message': 'OK' }.to_json]] | ||
rescue LoadError, ArgumentError => e | ||
[500, { 'Content-Type' => 'application/json' }, [{ 'message': e.message }.to_json]] | ||
end | ||
|
||
def do_first_call | ||
@first_call = true | ||
vcr.turn_off! | ||
WebMock.disable! if defined?(WebMock) | ||
rescue LoadError | ||
# nop | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
require 'cypress_on_rails/middleware_config' | ||
|
||
module CypressOnRails | ||
module Vcr | ||
# Provides helper methods for VCR middlewares | ||
module MiddlewareHelpers | ||
include MiddlewareConfig | ||
|
||
def vcr | ||
@vcr ||= configure_vcr | ||
end | ||
|
||
def cassette_library_dir | ||
configuration.vcr_options&.fetch(:cassette_library_dir) do | ||
"#{configuration.install_folder}/fixtures/vcr_cassettes" | ||
end | ||
end | ||
|
||
private | ||
|
||
def configure_vcr | ||
require 'vcr' | ||
VCR.configure do |config| | ||
config.cassette_library_dir = cassette_library_dir | ||
apply_vcr_options(config) if configuration.vcr_options.present? | ||
end | ||
VCR | ||
end | ||
|
||
def apply_vcr_options(config) | ||
configuration.vcr_options.each do |option, value| | ||
next if option.to_sym == :cassette_library_dir | ||
|
||
apply_vcr_option(config, option, value) | ||
end | ||
end | ||
|
||
def apply_vcr_option(config, option, value) | ||
return unless config.respond_to?(option) || config.respond_to?("#{option}=") | ||
|
||
if config.respond_to?("#{option}=") | ||
config.send("#{option}=", value) | ||
elsif value.is_a?(Array) | ||
config.send(option, *value) | ||
else | ||
config.send(option, value) | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
require_relative 'middleware_helpers' | ||
|
||
module CypressOnRails | ||
module Vcr | ||
# Middleware to handle vcr with use_cassette | ||
class UseCassetteMiddleware | ||
include MiddlewareHelpers | ||
|
||
def initialize(app, vcr = nil) | ||
@app = app | ||
@vcr = vcr | ||
end | ||
|
||
def call(env) | ||
return @app.call(env) if should_not_use_vcr? | ||
|
||
initialize_vcr | ||
handle_request_with_vcr(env) | ||
end | ||
|
||
private | ||
|
||
def vcr_defined? | ||
defined?(VCR) != nil | ||
end | ||
|
||
def should_not_use_vcr? | ||
vcr_defined? && | ||
VCR.configuration.cassette_library_dir.present? && | ||
VCR.configuration.cassette_library_dir != cassette_library_dir | ||
end | ||
|
||
def initialize_vcr | ||
WebMock.enable! if defined?(WebMock) | ||
vcr.turn_on! | ||
end | ||
|
||
def handle_request_with_vcr(env) | ||
request = Rack::Request.new(env) | ||
cassette_name = fetch_request_cassette(request) | ||
vcr.use_cassette(cassette_name) do | ||
logger.info "Handle request with cassette name: #{cassette_name}" | ||
@app.call(env) | ||
end | ||
end | ||
|
||
def fetch_request_cassette(request) | ||
if request.path.start_with?('/graphql') && request.params.key?('operation') | ||
"#{request.path}/#{request.params['operation']}" | ||
else | ||
request.path | ||
end | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.