scenario_server 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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