scenario_server 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.pryrc ADDED
@@ -0,0 +1,3 @@
1
+ Pry.commands.alias_command 'c', 'continue'
2
+ Pry.commands.alias_command 's', 'step'
3
+ Pry.commands.alias_command 'n', 'next'
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,57 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ scenario_server (0.0.1)
5
+ sequel (= 4.7)
6
+ sinatra (~> 1.4)
7
+ sinatra-contrib (~> 1.4)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ backports (3.6.0)
13
+ diff-lcs (1.2.5)
14
+ json_spec (1.1.1)
15
+ multi_json (~> 1.0)
16
+ rspec (~> 2.0)
17
+ multi_json (1.8.4)
18
+ rack (1.5.2)
19
+ rack-protection (1.5.2)
20
+ rack
21
+ rack-test (0.6.2)
22
+ rack (>= 1.0)
23
+ rake (10.1.1)
24
+ rspec (2.14.1)
25
+ rspec-core (~> 2.14.0)
26
+ rspec-expectations (~> 2.14.0)
27
+ rspec-mocks (~> 2.14.0)
28
+ rspec-core (2.14.7)
29
+ rspec-expectations (2.14.5)
30
+ diff-lcs (>= 1.1.3, < 2.0)
31
+ rspec-mocks (2.14.5)
32
+ sequel (4.7.0)
33
+ sinatra (1.4.4)
34
+ rack (~> 1.4)
35
+ rack-protection (~> 1.4)
36
+ tilt (~> 1.3, >= 1.3.4)
37
+ sinatra-contrib (1.4.2)
38
+ backports (>= 2.0)
39
+ multi_json
40
+ rack-protection
41
+ rack-test
42
+ sinatra (~> 1.4.0)
43
+ tilt (~> 1.3)
44
+ sqlite3 (1.3.8)
45
+ tilt (1.4.1)
46
+
47
+ PLATFORMS
48
+ ruby
49
+
50
+ DEPENDENCIES
51
+ bundler (~> 1.5)
52
+ json_spec (~> 1.1)
53
+ rack-test (~> 0.6)
54
+ rake (~> 10.1)
55
+ rspec (~> 2.0)
56
+ scenario_server!
57
+ sqlite3 (~> 1.3)
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Vaibhav Bhatia
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # Scenarios
2
+
3
+ This gem is used to setup a mock sinatra server. the routes can be defined via browser. Its main use case is to provide a mock rest api end point or for use with frank automation
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'scenarios'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install scenarios
18
+
19
+ ## Usage
20
+
21
+ This would provide with the following binaries
22
+ - scenarios
23
+ This will start a sinatra server on localhost:4567
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( http://github.com/<my-github-username>/scenarios/fork )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/scenarios ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ require 'scenarios/application/app.rb'
5
+ rescue LoadError
6
+ require 'rubygems'
7
+ require 'scenarios/application/app.rb'
8
+ end
9
+
10
+ ScenarioServer.run!
data/bin/scenariosdb ADDED
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ begin
5
+ require 'scenarios/Scenario_db.rb'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'scenarios/scenario_db.rb'
9
+ end
10
+
11
+ options = {}
12
+ opt_parser = OptionParser.new do |opts|
13
+
14
+ options[:setup] = false
15
+ opts.on('--setup', 'Setup the scenario db') do |g|
16
+ options[:setup] = g
17
+ end
18
+
19
+ options[:testdb] = false
20
+ opts.on('--testdb', 'database filename') do |t|
21
+ options[:testdb] = t
22
+ end
23
+
24
+ options[:add_scenario] = []
25
+ opts.on('--add-scenario name', Array, 'Add a scenario to the database') do |a|
26
+ options[:add_scenario] = a
27
+ end
28
+
29
+ options[:delete_scenario] = nil
30
+ opts.on('--delete-scenario id', Integer, 'Delete a scenario from the database with a given row id') do |b|
31
+ options[:delete_scenario] = b
32
+ end
33
+
34
+ options[:add_route] = []
35
+ opts.on('--add-route route_type, path, fixture, scenario_id', Array, 'Add a route to a scenario') do |c|
36
+ options[:add_route] = c
37
+ end
38
+
39
+ options[:delete_route] = nil
40
+ opts.on('--delete-route id', Integer, "Delete a route from the database with a given row id") do |d|
41
+ options[:delete_route] = d
42
+ end
43
+
44
+ options[:add_testdata] = []
45
+ opts.on('--add-testdata name,value,scenario_id', Array, "Add a testdata value to a scenario") do |e|
46
+ options[:add_testdata] = e
47
+ end
48
+
49
+ options[:delete_testdata] = nil
50
+ opts.on('--delete-testdata id', Integer, "Delete a testdata from the database with a given row id") do |f|
51
+ options[:delete_route] = f
52
+ end
53
+
54
+ options[:scenarios] = false
55
+ opts.on('--scenarios', 'List the scenarios in the database') do |h|
56
+ options[:scenarios] = h
57
+ end
58
+
59
+ options[:routes] = false
60
+ opts.on('--routes', 'List the routes in the database') do |i|
61
+ options[:routes] = i
62
+ end
63
+
64
+ opts.on('-h', '--help', 'Display this screen') do
65
+ puts opts
66
+ exit
67
+ end
68
+ end
69
+
70
+ begin
71
+ opt_parser.parse!
72
+ rescue OptionParser::ParseError => error
73
+ $stderr.puts error
74
+ $stderr.puts '(-h or --help will show valid options)'
75
+ exit 1
76
+ end
77
+
78
+ ScenarioDB.new(options)
@@ -0,0 +1,8 @@
1
+ {
2
+ "scenarios": [
3
+ {
4
+ "id": 1,
5
+ "name": "default"
6
+ }
7
+ ]
8
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "id": 1,
3
+ "name": "default"
4
+ }
@@ -0,0 +1 @@
1
+ {"url":"/scenarios/3"}
@@ -0,0 +1,234 @@
1
+ require 'sinatra'
2
+ require 'sinatra/respond_with'
3
+ require 'sequel'
4
+ require 'json'
5
+ require_relative '../scenario_db'
6
+ require_relative './app_helpers.rb'
7
+
8
+ class ScenarioServer < Sinatra::Base
9
+ DEFAULT_SCENARIO = "default"
10
+ attr_accessor :db, :scenario_db, :scenarios, :routes, :testdata
11
+ use Rack::MethodOverride
12
+
13
+ configure :production do
14
+ puts 'Production Environment'
15
+ set :db_file , File.dirname(File.expand_path(__FILE__)) + '/../data/scenario_db.sqlite3'
16
+ set :scenario, DEFAULT_SCENARIO
17
+ enable :logging
18
+ end
19
+
20
+ configure :development do
21
+ puts 'Development Environment'
22
+ set :db_file , File.dirname(File.expand_path(__FILE__)) + '/../data/scenario_db.sqlite3'
23
+ set :scenario, DEFAULT_SCENARIO
24
+ enable :logging
25
+ end
26
+
27
+ configure :test do
28
+ puts 'Test Environment'
29
+ set :db_file , File.dirname(File.expand_path(__FILE__)) + '/../data/scenario_testdb.sqlite3'
30
+ set :scenario, DEFAULT_SCENARIO
31
+ enable :logging
32
+ end
33
+
34
+ before do
35
+ options = {:db_file=>settings.db_file}
36
+ self.scenario_db = ScenarioDB.new(options)
37
+ self.scenario_db.configure_database
38
+ self.scenario_db.add_scenario('default')
39
+ end
40
+
41
+ get '/scenarios' do
42
+
43
+ ordered_scenarios = self.scenario_db.get_ordered_scenarios
44
+
45
+ if (request.env['HTTP_ACCEPT'] && request.env['HTTP_ACCEPT'].include?('text/html'))
46
+ erb :'index', :locals => { :scenarios => ordered_scenarios }
47
+ else
48
+ content_type 'application/json', :charset => 'utf-8'
49
+ content = {'scenarios'=>ordered_scenarios}.to_json
50
+ [200,content]
51
+ end
52
+ end
53
+
54
+ get '/scenarios/:scenario_id' do
55
+
56
+ selected_scenario = self.scenario_db.get_scenario_for_id(params[:scenario_id])
57
+ routes = self.scenario_db.get_routes_for_scenario(params[:scenario_id])
58
+
59
+ if (request.env['HTTP_ACCEPT'] && request.env['HTTP_ACCEPT'].include?('text/html'))
60
+ if params.has_key?('error')
61
+ erb :'scenario', :locals => {'scenario'=>selected_scenario, 'routes'=>routes, 'error'=>params['error']}
62
+ else
63
+ erb :'scenario', :locals => {'scenario'=>selected_scenario, 'routes'=>routes, 'error'=>'' }
64
+ end
65
+
66
+ else
67
+ content_type 'application/json', :charset => 'utf-8'
68
+ content = selected_scenario.to_json
69
+ [200,content]
70
+ end
71
+ end
72
+
73
+ post '/scenarios/new' do
74
+ if (request.env['HTTP_ACCEPT'] && request.env['HTTP_ACCEPT'].include?('text/html'))
75
+ self.scenario_db.add_scenario(params[:new_scenario])
76
+ redirect('/scenarios')
77
+ else
78
+ name = request.body.read
79
+ scenario_id = self.scenario_db.add_scenario(name)
80
+
81
+ [200,{"url"=>"/scenarios/"+scenario_id.to_s}.to_json]
82
+ end
83
+ end
84
+
85
+ delete '/scenarios/:scenario_id' do
86
+ self.scenario_db.delete_scenario_for_id(params[:scenario_id])
87
+
88
+ if (request.env['HTTP_ACCEPT'] && request.env['HTTP_ACCEPT'].include?('text/html'))
89
+ redirect('/scenarios')
90
+ else
91
+ [200]
92
+ end
93
+ end
94
+
95
+ post '/scenarios/:scenario_id/routes/new' do
96
+ if (request.env['HTTP_ACCEPT'] && request.env['HTTP_ACCEPT'].include?('text/html'))
97
+
98
+ valid_fixture = validate_json_string(params['fixture'])
99
+
100
+ if valid_fixture
101
+ self.scenario_db.add_route_for_scenario(params['route_type'],
102
+ params['path'], params['fixture'], params[:scenario_id])
103
+ redirect('/scenarios/'+params[:scenario_id])
104
+ else
105
+ redirect('/scenarios/'+params[:scenario_id]+'?error=invalid%20json')
106
+ end
107
+
108
+ else
109
+ json_body = JSON.parse(request.body.read)
110
+ route_id = self.scenario_db.add_route_for_scenario(json_body['route_type'],
111
+ json_body['path'], json_body['fixture'], params[:scenario_id])
112
+ content = {'url'=>'/scenarios/'+params[:scenario_id]+'/routes/'+route_id.to_s}.to_json
113
+ [200, content]
114
+ end
115
+ end
116
+
117
+ get '/scenarios/:scenario_id/routes' do
118
+ routes = self.scenario_db.get_routes_for_scenario(params[:scenario_id])
119
+
120
+ if (request.env['HTTP_ACCEPT'] && request.env['HTTP_ACCEPT'].include?('text/html'))
121
+ erb :'scenario', :locals => { :routes => routes }
122
+ else
123
+ content_type 'application/json', :charset => 'utf-8'
124
+ content = {'routes'=>routes}.to_json
125
+
126
+ [200,content]
127
+ end
128
+ end
129
+
130
+ delete '/scenarios/:scenario_id/routes/:route_id' do
131
+ self.scenario_db.delete_route(params[:route_id])
132
+
133
+ if (request.env['HTTP_ACCEPT'] && request.env['HTTP_ACCEPT'].include?('text/html'))
134
+ redirect('/scenarios/'+ params[:scenario_id] )
135
+ else
136
+ [200]
137
+ end
138
+ end
139
+
140
+ get '/scenarios/:scenario_id/routes/:route_id' do
141
+ route = self.scenario_db.get_route(params[:route_id])
142
+
143
+
144
+ if (request.env['HTTP_ACCEPT'] && request.env['HTTP_ACCEPT'].include?('text/html'))
145
+ erb :'route', :locals => { :route => route }
146
+ else
147
+ content_type 'application/json', :charset => 'utf-8'
148
+ content = route.to_json
149
+
150
+ [200,content]
151
+ end
152
+ end
153
+
154
+ #default scenario
155
+
156
+ get '/scenario' do
157
+ [200, settings.scenario]
158
+ end
159
+
160
+ put '/scenario/:new_scenario' do
161
+ name = params[:new_scenario]
162
+ if valid_scenario(name)
163
+ settings.scenario = name
164
+ 200
165
+ else
166
+ 400
167
+ end
168
+ end
169
+
170
+ delete '/scenario' do
171
+ settings.scenario = DEFAULT_SCENARIO
172
+ 200
173
+ end
174
+
175
+ # route path calls
176
+ get "/v*" do
177
+ content_type 'application/json'
178
+
179
+ route_type = request.request_method.upcase
180
+ path = request.path.downcase
181
+
182
+ fixture = get_fixture(route_type, path,settings.scenario)
183
+ if fixture.nil?
184
+ 404
185
+ else
186
+ fixture
187
+ end
188
+ end
189
+
190
+ post "/v*" do
191
+ content_type 'application/json'
192
+
193
+ route_type = request.request_method.upcase
194
+ path = request.path.downcase
195
+
196
+ fixture = get_fixture(route_type, path,settings.scenario)
197
+ if fixture.nil?
198
+ 404
199
+ else
200
+ fixture
201
+ end
202
+ end
203
+
204
+ put "/v*" do
205
+ content_type 'application/json'
206
+
207
+ route_type = request.request_method.upcase
208
+ path = request.path.downcase
209
+
210
+ fixture = get_fixture(route_type, path,settings.scenario)
211
+ if fixture.nil?
212
+ 404
213
+ else
214
+ fixture
215
+ end
216
+ end
217
+
218
+ delete "/v*" do
219
+ content_type 'application/json'
220
+
221
+ route_type = request.request_method.upcase
222
+ path = request.path.downcase
223
+
224
+ fixture = get_fixture(route_type, path,settings.scenario)
225
+ if fixture.nil?
226
+ 404
227
+ else
228
+ fixture
229
+ end
230
+ end
231
+
232
+
233
+ end
234
+
@@ -0,0 +1,30 @@
1
+ require 'json'
2
+ require_relative '../scenario_db'
3
+
4
+ def validate_json_string (fixture)
5
+ begin
6
+ data = JSON.parse(fixture)
7
+ return true
8
+ rescue JSON::ParserError => e
9
+ return false
10
+ end
11
+ end
12
+
13
+ def valid_scenario (scenario_name)
14
+ scenarios = self.scenario_db.get_scenario_names
15
+ scenarios.include?(scenario_name)
16
+ end
17
+
18
+ def default?(name)
19
+ name == "default"
20
+ end
21
+
22
+ def get_fixture(route_type, path, scenario_name)
23
+ fixture = self.scenario_db.get_fixture_from_routes(route_type, path, scenario_name)
24
+
25
+ if fixture.nil? and default?(scenario_name)
26
+ fixture = self.scenario_db.get_fixture_from_routes(route_type, path, 'default')
27
+ end
28
+
29
+ fixture
30
+ end
@@ -0,0 +1,43 @@
1
+ <html xmlns="http://www.w3.org/1999/html">
2
+
3
+ <body>
4
+ <h1>Scenarios</h1>
5
+ <table>
6
+ <caption>Scenarios</caption>
7
+ <thead>
8
+ <tr>
9
+ <th>ID</th>
10
+ <th>Name</th>
11
+ <th>Actions</th>
12
+ </tr>
13
+ </thead>
14
+ <tbody>
15
+ <% scenarios.each do |scenario| %>
16
+ <tr>
17
+ <td><%= scenario[:id] %></td>
18
+ <td><a href="/scenarios/<%= scenario[:id] %>"><%= scenario[:name] %></a></td>
19
+ <td>
20
+ <form action="/scenarios/<%= scenario[:id] %>" method="post" style="display:inline;">
21
+ <input name="_method" value="delete" type="hidden"/>
22
+ <input type="submit" name="commit" value="Delete">
23
+ </form>
24
+ </td>
25
+ </tr>
26
+ <% end %>
27
+ </tbody>
28
+ </table>
29
+ <p>
30
+ <form action="/scenarios/new" method="post">
31
+ <!--<input type="hidden" name="_method" value="POST" />-->
32
+ <p>
33
+ <label>New scenario</label><br/>
34
+ <input type="text" name="new_scenario">
35
+ </p>
36
+ <p>
37
+ <button type="submit">Submit</button>
38
+ </p>
39
+ </form>
40
+ </p>
41
+ </body>
42
+
43
+ </html>
@@ -0,0 +1,30 @@
1
+ <html>
2
+ <body>
3
+ <h1><%= route[:path] %></h1>
4
+ <table>
5
+ <caption>Route</caption>
6
+ <thead>
7
+ <tr>
8
+ <th>ID</th>
9
+ <th>Scenario ID</th>
10
+ <th>Route Type</th>
11
+ <th>Path</th>
12
+ <th>Fixture</th>
13
+ <th>Created At</th>
14
+ <th>Updated At</th>
15
+ </tr>
16
+ </thead>
17
+ <tbody>
18
+ <tr>
19
+ <td><%=route[:id]%></td>
20
+ <td><%=route[:scenario_id]%></td>
21
+ <td><%=route[:route_type]%></td>
22
+ <td><%=route[:path]%></td>
23
+ <td><%=route[:fixture]%></td>
24
+ <td><%=route[:created_at]%></td>
25
+ <td><%=route[:updated_at]%></td>
26
+ </tr>
27
+ </tbody>
28
+ </table>
29
+ </body>
30
+ </html>
@@ -0,0 +1,56 @@
1
+ <html>
2
+ <body>
3
+ <a href="/scenarios">Home</a>
4
+ <br>
5
+
6
+ <%= error %>
7
+ <h2><%= scenario[:name] %></h2>
8
+ <table>
9
+ <thead>
10
+ <tr>
11
+ <th>Request Type</th>
12
+ <th>Path</th>
13
+ <th>Fixture</th>
14
+ </tr>
15
+ </thead>
16
+ <tbody>
17
+ <% routes.each do |route| %>
18
+ <tr>
19
+ <td><%= route[:route_type] %></td>
20
+ <td><a href="/scenarios/<%= scenario[:id] %>/routes/<%= route[:id]%>"><%= route[:path] %></a></td>
21
+ <td><%= route[:fixture] %></td>
22
+ <td>
23
+ <form action="/scenarios/<%= scenario[:id] %>/routes/<%= route[:id]%>" method="post" style="display:inline;">
24
+ <input name="_method" value="delete" type="hidden"/>
25
+ <input type="submit" name="commit" value="Delete">
26
+ </form>
27
+ </td>
28
+ </tr>
29
+ <% end %>
30
+ </tbody>
31
+ </table>
32
+ <p>
33
+ <form action="/scenarios/<%= scenario[:id] %>/routes/new" method="post" id="routeform">
34
+ <p>
35
+
36
+ <label>Request Type</label>
37
+ <select name="route_type">
38
+ <option value="GET">GET</option>
39
+ <option value="POST">POST</option>
40
+ <option value="DELETE">DELETE</option>
41
+ <option value="PUT">PUT</option>
42
+ </select>
43
+ <br>
44
+ <label>Path</label>
45
+ <input type="text" name="path"> <br>
46
+ <label>Fixture</label>
47
+ <textarea name="fixture" rows="10" ></textarea>
48
+ </p>
49
+ <p>
50
+ <button type="submit">Submit</button>
51
+ </p>
52
+ </form>
53
+ </p>
54
+
55
+ </body>
56
+ </html>
@@ -0,0 +1 @@
1
+ only sqlite files in this directory