-
-
Notifications
You must be signed in to change notification settings - Fork 60
/
Copy pathmiddleware.rb
81 lines (70 loc) · 2.29 KB
/
middleware.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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
require 'json'
require 'rack'
require 'cypress_on_rails/configuration'
require 'cypress_on_rails/command_executor'
require 'cypress_on_rails/vcr_wrapper'
module CypressOnRails
# Middleware to handle cypress commands and eval
class Middleware
def initialize(app, command_executor = CommandExecutor, file = ::File)
@app = app
@command_executor = command_executor
@file = file
end
def call(env)
request = Rack::Request.new(env)
if request.path.start_with?('/__cypress__/command')
configuration.tagged_logged { handle_command(request) }
elsif defined?(VCR) && configuration.use_vcr
VCRWrapper.new(app: @app, env: env).run_with_cassette
else
@app.call(env)
end
end
private
def configuration
CypressOnRails.configuration
end
def logger
configuration.logger
end
Command = Struct.new(:name, :options, :cypress_folder) do
# @return [Array<Cypress::Middleware::Command>]
def self.from_body(body, configuration)
if body.is_a?(Array)
command_params = body
else
command_params = [body]
end
command_params.map do |params|
new(params.fetch('name'), params['options'], configuration.cypress_folder)
end
end
def file_path
"#{cypress_folder}/app_commands/#{name}.rb"
end
end
def handle_command(req)
body = JSON.parse(req.body.read)
logger.info "handle_command: #{body}"
commands = Command.from_body(body, configuration)
missing_command = commands.find {|command| [email protected]?(command.file_path) }
if missing_command.nil?
begin
results = commands.map { |command| @command_executor.perform(command.file_path, command.options) }
begin
output = results.to_json
rescue NoMethodError
output = {"message" => "Cannot convert to json"}.to_json
end
[201, {'Content-Type' => 'application/json'}, [output]]
rescue => e
output = {"message" => e.message, "class" => e.class.to_s}.to_json
[500, {'Content-Type' => 'application/json'}, [output]]
end
else
[404, {}, ["could not find command file: #{missing_command.file_path}"]]
end
end
end
end