putsreq 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (233) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +7 -0
  3. data/.coffeelint.json +5 -0
  4. data/.gitignore +20 -0
  5. data/.hound.yml +14 -0
  6. data/.jshintrc +3 -0
  7. data/.rspec +3 -0
  8. data/.rubocop.yml +110 -0
  9. data/.ruby-version +1 -0
  10. data/.travis.yml +18 -0
  11. data/Gemfile +91 -0
  12. data/Gemfile.lock +270 -0
  13. data/LICENSE +5 -0
  14. data/Procfile +1 -0
  15. data/README.md +147 -0
  16. data/Rakefile +8 -0
  17. data/app/assets/javascripts/application.js +27 -0
  18. data/app/assets/javascripts/buckets.js.coffee +68 -0
  19. data/app/assets/javascripts/initializers.js.coffee +8 -0
  20. data/app/assets/stylesheets/application.css +15 -0
  21. data/app/assets/stylesheets/base.css +68 -0
  22. data/app/assets/stylesheets/buckets.css.scss +91 -0
  23. data/app/assets/stylesheets/helpers.css +154 -0
  24. data/app/controllers/application_controller.rb +35 -0
  25. data/app/controllers/buckets_controller.rb +88 -0
  26. data/app/controllers/concerns/.keep +0 -0
  27. data/app/controllers/home_controller.rb +18 -0
  28. data/app/helpers/application_helper.rb +14 -0
  29. data/app/interactors/create_request.rb +15 -0
  30. data/app/interactors/create_response.rb +11 -0
  31. data/app/interactors/eval_response_builder.rb +55 -0
  32. data/app/interactors/filter_headers.rb +28 -0
  33. data/app/interactors/forward_request.rb +39 -0
  34. data/app/interactors/notify_count.rb +15 -0
  35. data/app/interactors/record_request.rb +5 -0
  36. data/app/mailers/.keep +0 -0
  37. data/app/models/.keep +0 -0
  38. data/app/models/bucket.rb +99 -0
  39. data/app/models/concerns/.keep +0 -0
  40. data/app/models/request.rb +36 -0
  41. data/app/models/response.rb +22 -0
  42. data/app/models/user.rb +42 -0
  43. data/app/views/buckets/_buttons.html.erb +4 -0
  44. data/app/views/buckets/_form.html.erb +33 -0
  45. data/app/views/buckets/_readonly_buttons.html.erb +1 -0
  46. data/app/views/buckets/_requests.html.erb +45 -0
  47. data/app/views/buckets/show.html.erb +58 -0
  48. data/app/views/home/index.html.erb +45 -0
  49. data/app/views/layouts/_header.html.erb +18 -0
  50. data/app/views/layouts/application.html.erb +28 -0
  51. data/app/views/layouts/devise.html.erb +22 -0
  52. data/app/views/shared/_flash.html.erb +10 -0
  53. data/app/views/users/confirmations/new.html.erb +12 -0
  54. data/app/views/users/mailer/confirmation_instructions.html.erb +5 -0
  55. data/app/views/users/mailer/reset_password_instructions.html.erb +8 -0
  56. data/app/views/users/mailer/unlock_instructions.html.erb +7 -0
  57. data/app/views/users/passwords/edit.html.erb +32 -0
  58. data/app/views/users/passwords/new.html.erb +23 -0
  59. data/app/views/users/registrations/edit.html.erb +59 -0
  60. data/app/views/users/registrations/new.html.erb +46 -0
  61. data/app/views/users/sessions/new.html.erb +38 -0
  62. data/app/views/users/shared/_links.erb +25 -0
  63. data/app/views/users/unlocks/new.html.erb +12 -0
  64. data/bin/bundle +3 -0
  65. data/bin/putsreq +71 -0
  66. data/bin/rails +4 -0
  67. data/bin/rake +4 -0
  68. data/bin/rspec +16 -0
  69. data/config.ru +4 -0
  70. data/config/application.rb +42 -0
  71. data/config/boot.rb +4 -0
  72. data/config/environment.rb +5 -0
  73. data/config/environments/development.rb +33 -0
  74. data/config/environments/production.rb +82 -0
  75. data/config/environments/test.rb +36 -0
  76. data/config/initializers/backtrace_silencers.rb +7 -0
  77. data/config/initializers/devise.rb +256 -0
  78. data/config/initializers/filter_parameter_logging.rb +4 -0
  79. data/config/initializers/inflections.rb +16 -0
  80. data/config/initializers/mime_types.rb +5 -0
  81. data/config/initializers/redis.rb +17 -0
  82. data/config/initializers/secret_token.rb +12 -0
  83. data/config/initializers/session_store.rb +3 -0
  84. data/config/initializers/setup_email.rb +10 -0
  85. data/config/initializers/wrap_parameters.rb +14 -0
  86. data/config/locales/devise.en.yml +59 -0
  87. data/config/locales/en.yml +23 -0
  88. data/config/mongoid.yml +47 -0
  89. data/config/routes.rb +15 -0
  90. data/config/unicorn.rb +16 -0
  91. data/lib/assets/.keep +0 -0
  92. data/lib/putsreq/version.rb +3 -0
  93. data/lib/tasks/.keep +0 -0
  94. data/public/404.html +58 -0
  95. data/public/422.html +58 -0
  96. data/public/500.html +57 -0
  97. data/public/favicon.ico +0 -0
  98. data/public/images/.keep +0 -0
  99. data/public/images/favicon.png +0 -0
  100. data/public/images/favicon144.png +0 -0
  101. data/public/images/favicon152.png +0 -0
  102. data/public/images/glyphicons-halflings-white.png +0 -0
  103. data/public/images/glyphicons-halflings.png +0 -0
  104. data/public/images/logo.png +0 -0
  105. data/public/javascripts/vendor/ace/theme-monokai.js +1 -0
  106. data/public/javascripts/vendor/ace/theme-textmate.js +1 -0
  107. data/public/javascripts/vendor/ace/worker-javascript.js +1 -0
  108. data/public/javascripts/vendor/ace/worker-json.js +1 -0
  109. data/public/robots.txt +5 -0
  110. data/putsreq.gemspec +22 -0
  111. data/spec/controllers/buckets_controller_spec.rb +164 -0
  112. data/spec/interactors/create_request_spec.rb +34 -0
  113. data/spec/interactors/create_response_spec.rb +14 -0
  114. data/spec/interactors/eval_response_builder_spec.rb +63 -0
  115. data/spec/interactors/forward_request_spec.rb +39 -0
  116. data/spec/models/bucket_spec.rb +96 -0
  117. data/spec/models/user_spec.rb +5 -0
  118. data/spec/spec_helper.rb +66 -0
  119. data/vendor/assets/javascripts/.keep +0 -0
  120. data/vendor/assets/javascripts/ace/ace.js +10 -0
  121. data/vendor/assets/javascripts/ace/ext-searchbox.js +1 -0
  122. data/vendor/assets/javascripts/ace/ext-spellcheck.js +1 -0
  123. data/vendor/assets/javascripts/ace/ext-static_highlight.js +1 -0
  124. data/vendor/assets/javascripts/ace/ext-textarea.js +1 -0
  125. data/vendor/assets/javascripts/ace/keybinding-emacs.js +1 -0
  126. data/vendor/assets/javascripts/ace/keybinding-vim.js +1 -0
  127. data/vendor/assets/javascripts/ace/mode-abap.js +1 -0
  128. data/vendor/assets/javascripts/ace/mode-asciidoc.js +1 -0
  129. data/vendor/assets/javascripts/ace/mode-c9search.js +1 -0
  130. data/vendor/assets/javascripts/ace/mode-c_cpp.js +1 -0
  131. data/vendor/assets/javascripts/ace/mode-clojure.js +1 -0
  132. data/vendor/assets/javascripts/ace/mode-coffee.js +1 -0
  133. data/vendor/assets/javascripts/ace/mode-coldfusion.js +1 -0
  134. data/vendor/assets/javascripts/ace/mode-csharp.js +1 -0
  135. data/vendor/assets/javascripts/ace/mode-css.js +1 -0
  136. data/vendor/assets/javascripts/ace/mode-curly.js +1 -0
  137. data/vendor/assets/javascripts/ace/mode-dart.js +1 -0
  138. data/vendor/assets/javascripts/ace/mode-diff.js +1 -0
  139. data/vendor/assets/javascripts/ace/mode-django.js +1 -0
  140. data/vendor/assets/javascripts/ace/mode-dot.js +1 -0
  141. data/vendor/assets/javascripts/ace/mode-glsl.js +1 -0
  142. data/vendor/assets/javascripts/ace/mode-golang.js +1 -0
  143. data/vendor/assets/javascripts/ace/mode-groovy.js +1 -0
  144. data/vendor/assets/javascripts/ace/mode-haml.js +1 -0
  145. data/vendor/assets/javascripts/ace/mode-haxe.js +1 -0
  146. data/vendor/assets/javascripts/ace/mode-html.js +1 -0
  147. data/vendor/assets/javascripts/ace/mode-jade.js +1 -0
  148. data/vendor/assets/javascripts/ace/mode-java.js +1 -0
  149. data/vendor/assets/javascripts/ace/mode-javascript.js +1 -0
  150. data/vendor/assets/javascripts/ace/mode-json.js +1 -0
  151. data/vendor/assets/javascripts/ace/mode-jsp.js +1 -0
  152. data/vendor/assets/javascripts/ace/mode-jsx.js +1 -0
  153. data/vendor/assets/javascripts/ace/mode-latex.js +1 -0
  154. data/vendor/assets/javascripts/ace/mode-less.js +1 -0
  155. data/vendor/assets/javascripts/ace/mode-liquid.js +1 -0
  156. data/vendor/assets/javascripts/ace/mode-lisp.js +1 -0
  157. data/vendor/assets/javascripts/ace/mode-livescript.js +1 -0
  158. data/vendor/assets/javascripts/ace/mode-lua.js +1 -0
  159. data/vendor/assets/javascripts/ace/mode-luapage.js +1 -0
  160. data/vendor/assets/javascripts/ace/mode-lucene.js +1 -0
  161. data/vendor/assets/javascripts/ace/mode-makefile.js +1 -0
  162. data/vendor/assets/javascripts/ace/mode-markdown.js +1 -0
  163. data/vendor/assets/javascripts/ace/mode-objectivec.js +1 -0
  164. data/vendor/assets/javascripts/ace/mode-ocaml.js +1 -0
  165. data/vendor/assets/javascripts/ace/mode-perl.js +1 -0
  166. data/vendor/assets/javascripts/ace/mode-pgsql.js +1 -0
  167. data/vendor/assets/javascripts/ace/mode-php.js +1 -0
  168. data/vendor/assets/javascripts/ace/mode-powershell.js +1 -0
  169. data/vendor/assets/javascripts/ace/mode-python.js +1 -0
  170. data/vendor/assets/javascripts/ace/mode-r.js +1 -0
  171. data/vendor/assets/javascripts/ace/mode-rdoc.js +1 -0
  172. data/vendor/assets/javascripts/ace/mode-rhtml.js +1 -0
  173. data/vendor/assets/javascripts/ace/mode-ruby.js +1 -0
  174. data/vendor/assets/javascripts/ace/mode-scad.js +1 -0
  175. data/vendor/assets/javascripts/ace/mode-scala.js +1 -0
  176. data/vendor/assets/javascripts/ace/mode-scheme.js +1 -0
  177. data/vendor/assets/javascripts/ace/mode-scss.js +1 -0
  178. data/vendor/assets/javascripts/ace/mode-sh.js +1 -0
  179. data/vendor/assets/javascripts/ace/mode-sql.js +1 -0
  180. data/vendor/assets/javascripts/ace/mode-stylus.js +1 -0
  181. data/vendor/assets/javascripts/ace/mode-svg.js +1 -0
  182. data/vendor/assets/javascripts/ace/mode-tcl.js +1 -0
  183. data/vendor/assets/javascripts/ace/mode-tex.js +1 -0
  184. data/vendor/assets/javascripts/ace/mode-text.js +0 -0
  185. data/vendor/assets/javascripts/ace/mode-textile.js +1 -0
  186. data/vendor/assets/javascripts/ace/mode-tm_snippet.js +1 -0
  187. data/vendor/assets/javascripts/ace/mode-typescript.js +1 -0
  188. data/vendor/assets/javascripts/ace/mode-vbscript.js +1 -0
  189. data/vendor/assets/javascripts/ace/mode-xml.js +1 -0
  190. data/vendor/assets/javascripts/ace/mode-xquery.js +1 -0
  191. data/vendor/assets/javascripts/ace/mode-yaml.js +1 -0
  192. data/vendor/assets/javascripts/ace/theme-ambiance.js +1 -0
  193. data/vendor/assets/javascripts/ace/theme-chaos.js +1 -0
  194. data/vendor/assets/javascripts/ace/theme-chrome.js +1 -0
  195. data/vendor/assets/javascripts/ace/theme-clouds.js +1 -0
  196. data/vendor/assets/javascripts/ace/theme-clouds_midnight.js +1 -0
  197. data/vendor/assets/javascripts/ace/theme-cobalt.js +1 -0
  198. data/vendor/assets/javascripts/ace/theme-crimson_editor.js +1 -0
  199. data/vendor/assets/javascripts/ace/theme-dawn.js +1 -0
  200. data/vendor/assets/javascripts/ace/theme-dreamweaver.js +1 -0
  201. data/vendor/assets/javascripts/ace/theme-eclipse.js +1 -0
  202. data/vendor/assets/javascripts/ace/theme-github.js +1 -0
  203. data/vendor/assets/javascripts/ace/theme-idle_fingers.js +1 -0
  204. data/vendor/assets/javascripts/ace/theme-kr.js +1 -0
  205. data/vendor/assets/javascripts/ace/theme-merbivore.js +1 -0
  206. data/vendor/assets/javascripts/ace/theme-merbivore_soft.js +1 -0
  207. data/vendor/assets/javascripts/ace/theme-mono_industrial.js +1 -0
  208. data/vendor/assets/javascripts/ace/theme-monokai.js +1 -0
  209. data/vendor/assets/javascripts/ace/theme-pastel_on_dark.js +1 -0
  210. data/vendor/assets/javascripts/ace/theme-solarized_dark.js +1 -0
  211. data/vendor/assets/javascripts/ace/theme-solarized_light.js +1 -0
  212. data/vendor/assets/javascripts/ace/theme-textmate.js +1 -0
  213. data/vendor/assets/javascripts/ace/theme-tomorrow.js +1 -0
  214. data/vendor/assets/javascripts/ace/theme-tomorrow_night.js +1 -0
  215. data/vendor/assets/javascripts/ace/theme-tomorrow_night_blue.js +1 -0
  216. data/vendor/assets/javascripts/ace/theme-tomorrow_night_bright.js +1 -0
  217. data/vendor/assets/javascripts/ace/theme-tomorrow_night_eighties.js +1 -0
  218. data/vendor/assets/javascripts/ace/theme-twilight.js +1 -0
  219. data/vendor/assets/javascripts/ace/theme-vibrant_ink.js +1 -0
  220. data/vendor/assets/javascripts/ace/theme-xcode.js +1 -0
  221. data/vendor/assets/javascripts/ace/worker-coffee.js +1 -0
  222. data/vendor/assets/javascripts/ace/worker-css.js +1 -0
  223. data/vendor/assets/javascripts/ace/worker-javascript.js +1 -0
  224. data/vendor/assets/javascripts/ace/worker-json.js +1 -0
  225. data/vendor/assets/javascripts/ace/worker-php.js +1 -0
  226. data/vendor/assets/javascripts/ace/worker-xquery.js +1 -0
  227. data/vendor/assets/javascripts/jquery.tipsy.js +198 -0
  228. data/vendor/assets/javascripts/mode-javascript.js +1 -0
  229. data/vendor/assets/javascripts/theme-monokai.js +1 -0
  230. data/vendor/assets/javascripts/worker-javascript.js +1 -0
  231. data/vendor/assets/stylesheets/.keep +0 -0
  232. data/vendor/assets/stylesheets/tipsy.css +25 -0
  233. metadata +311 -0
@@ -0,0 +1,15 @@
1
+ class NotifyCount
2
+ include Interactor
3
+
4
+ delegate :bucket, :built_request, to: :context
5
+
6
+ def call
7
+ return unless ENV['PUSHER_URL']
8
+
9
+ Pusher["channel_requests_#{bucket.token}"].trigger('new',
10
+ count: bucket.requests_count,
11
+ request: built_request)
12
+ rescue => e
13
+ Rails.logger.error(e)
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ class RecordRequest
2
+ include Interactor::Organizer
3
+
4
+ organize CreateRequest, EvalResponseBuilder, ForwardRequest, CreateResponse, NotifyCount
5
+ end
File without changes
File without changes
@@ -0,0 +1,99 @@
1
+ class Bucket
2
+ include Mongoid::Document
3
+ include Mongoid::Timestamps
4
+
5
+ has_many :forks, class_name: 'Bucket'
6
+
7
+ belongs_to :fork, class_name: 'Bucket'
8
+ belongs_to :user
9
+
10
+ field :token
11
+ field :name
12
+ field :owner_token
13
+ field :response_builder, default: -> { default_response_builder }
14
+ field :history_start_at, type: Time
15
+
16
+ index token: 1
17
+ index owner_token: 1
18
+ index fork_id: 1
19
+
20
+ index({ updated_at: 1 }, { expire_after_seconds: 1.month })
21
+
22
+ before_create :generate_token
23
+
24
+ def requests
25
+ # I couldn't make has_many + conditions work with Mongoid
26
+ # requests must be filtered by created_at
27
+ # see clear_history
28
+
29
+ Request.where(bucket_id: id).gte(created_at: history_start_at || created_at).order(:created_at.desc)
30
+ end
31
+
32
+ def responses
33
+ # I couldn't make has_many + conditions work with Mongoid
34
+ # responses must be filtered by created_at
35
+ # see clear_history
36
+ Response.where(bucket_id: id).gte(created_at: history_start_at || created_at).order(:created_at.desc)
37
+ end
38
+
39
+ def clear_history
40
+ # requests and responses are capped collections in production, we cannot delete docs on a capped collection
41
+ # so we filter these objects by the history_start_at to "clear"
42
+ # db.runCommand({ "convertToCapped": "requests", size: 25000000 });
43
+ # db.runCommand({ "convertToCapped": "responses", size: 25000000 });
44
+ update_attribute :history_start_at, Time.now
45
+ end
46
+
47
+ def name
48
+ if (name = read_attribute(:name)).blank?
49
+ token
50
+ else
51
+ name
52
+ end
53
+ end
54
+
55
+ def last_request
56
+ requests.order(:created_at.desc).first
57
+ end
58
+
59
+ def last_response
60
+ responses.order(:created_at.desc).first
61
+ end
62
+
63
+ def last_request_at
64
+ last_request.try(:created_at)
65
+ end
66
+
67
+ def first_request_at
68
+ requests.order(:created_at.asc).first.try(:created_at)
69
+ end
70
+
71
+ def requests_count
72
+ requests.count
73
+ end
74
+
75
+ private
76
+
77
+ def generate_token
78
+ self.token = loop do
79
+ random_token = SecureRandom.urlsafe_base64(15).tr('_-', '0a')
80
+ break random_token unless Bucket.where(token: random_token).exists?
81
+ end
82
+ end
83
+
84
+ def default_response_builder
85
+ <<-DEFAULT.strip_heredoc
86
+ // Build a response
87
+ var msg = 'Hello World';
88
+
89
+ if(request.params.name) {
90
+ msg = 'Hello ' + request.params.name;
91
+ }
92
+
93
+ response.body = msg;
94
+
95
+ // Forward a request
96
+ // request.forwardTo = 'http://example.com/api';
97
+ DEFAULT
98
+ end
99
+ end
File without changes
@@ -0,0 +1,36 @@
1
+ class Request
2
+ include Mongoid::Document
3
+ include Mongoid::Timestamps
4
+
5
+ belongs_to :bucket, touch: true
6
+
7
+ has_one :response, dependent: :delete
8
+
9
+ field :body
10
+ field :headers, type: Hash
11
+ field :content_length
12
+ field :request_method
13
+ field :ip
14
+ field :url
15
+ field :params, type: Hash
16
+
17
+ index bucket_id: 1, created_at: -1
18
+
19
+ validates :bucket, presence: true
20
+
21
+ after_create :bump_requests_recorded
22
+
23
+ def body_as_string
24
+ body.is_a?(Hash) ? JSON.pretty_generate(body) : body.to_s
25
+ end
26
+
27
+ def headers_as_string
28
+ JSON.pretty_generate(headers.to_h)
29
+ end
30
+
31
+ private
32
+
33
+ def bump_requests_recorded
34
+ REDIS.incr 'requests_recorded'
35
+ end
36
+ end
@@ -0,0 +1,22 @@
1
+ class Response
2
+ include Mongoid::Document
3
+ include Mongoid::Timestamps
4
+
5
+ belongs_to :bucket
6
+ belongs_to :request
7
+
8
+ field :body, default: 'ok'
9
+ field :headers, type: Hash, default: { 'Content-Type' => 'text/plain' }
10
+ field :status, type: Integer, default: 200
11
+
12
+ # index created_at: 1, options { expireAfterSeconds: 604800 }
13
+ index bucket_id: 1, created_at: -1
14
+ index request_id: 1
15
+
16
+ validates :bucket, presence: true
17
+ validates :request, presence: true
18
+
19
+ def body_as_string
20
+ body.is_a?(Hash) ? JSON.pretty_generate(body) : body.to_s
21
+ end
22
+ end
@@ -0,0 +1,42 @@
1
+ class User
2
+ include Mongoid::Document
3
+ # Include default devise modules. Others available are:
4
+ # :confirmable, :lockable, :timeoutable and :omniauthable
5
+ devise :database_authenticatable, :registerable,
6
+ :recoverable, :rememberable, :trackable, :validatable
7
+
8
+ ## Database authenticatable
9
+ field :email, type: String, default: ""
10
+ field :encrypted_password, type: String, default: ""
11
+
12
+ ## Recoverable
13
+ field :reset_password_token, type: String
14
+ field :reset_password_sent_at, type: Time
15
+
16
+ ## Rememberable
17
+ field :remember_created_at, type: Time
18
+
19
+ ## Trackable
20
+ field :sign_in_count, type: Integer, default: 0
21
+ field :current_sign_in_at, type: Time
22
+ field :last_sign_in_at, type: Time
23
+ field :current_sign_in_ip, type: String
24
+ field :last_sign_in_ip, type: String
25
+
26
+ ## Confirmable
27
+ # field :confirmation_token, type: String
28
+ # field :confirmed_at, type: Time
29
+ # field :confirmation_sent_at, type: Time
30
+ # field :unconfirmed_email, type: String # Only if using reconfirmable
31
+
32
+ ## Lockable
33
+ # field :failed_attempts, type: Integer, default: 0 # Only if lock strategy is :failed_attempts
34
+ # field :unlock_token, type: String # Only if unlock strategy is :email or :both
35
+ # field :locked_at, type: Time
36
+
37
+ has_many :users
38
+
39
+ field :name
40
+
41
+ validates :name, presence: true
42
+ end
@@ -0,0 +1,4 @@
1
+ <button class="btn btn-primary tm10">Update</button>
2
+ <%= link_to 'Fork', bucket_fork_path(@bucket.token), class: 'btn btn-default tm10 lm5', method: :post %>
3
+ <%= link_to 'Clear History', bucket_clear_path(@bucket.token), class: 'btn btn-default tm10 lm5', method: :delete, data: { confirm: 'Are you sure?' } %>
4
+ <%= link_to 'Destroy', bucket_destroy_path(@bucket.token), class: 'btn btn-default tm10 lm5', method: :delete, data: { confirm: 'Are you sure?' } %>
@@ -0,0 +1,33 @@
1
+ <%= form_for @bucket, url: update_bucket_path(@bucket.token), method: :put do |f| %>
2
+ <%= f.hidden_field :response_builder %>
3
+ <script id="response-builder-container" type='application/vns.putsreq-response_builder'><%== @bucket.response_builder %></script>
4
+ <div class="row">
5
+ <div class="col-md-6">
6
+ <h4>Bucket name
7
+ <small><em>You can change it anytime.</em></small>
8
+ </h4>
9
+ <div class="input-group putsreq-name bm30">
10
+ <%= f.text_field :name %>
11
+ <% if @bucket.fork %>
12
+ <p><small>forked from <%= link_to @bucket.fork.name, bucket_path(@bucket.fork.token) %></small></p>
13
+ <% end %>
14
+ </div>
15
+ </div>
16
+ <div class="col-md-6">
17
+ <h4>Requests
18
+ <small><em>The number of requests made to this bucket.</em></small>
19
+ </h4>
20
+ <h3 id="bucket-request-count"><%= @bucket.requests_count %></h3>
21
+ </div>
22
+ </div>
23
+ <h4>Response Builder&nbsp;<a href="https://github.com/phstc/putsreq#response-builder" target="_blank"><span class="glyphicon glyphicon-info-sign"></span></a></h4>
24
+ <div id="editor" name="editor" style="width: 100%; height: 150px"></div>
25
+ <textarea id="response_builder" name="response_builder" style="display:none;"></textarea>
26
+ <p>
27
+ <% if is_owner?(@bucket) %>
28
+ <%= render 'buttons' %>
29
+ <% else %>
30
+ <%= render 'readonly_buttons' %>
31
+ <% end %>
32
+ </p>
33
+ <% end %>
@@ -0,0 +1 @@
1
+ <%= link_to 'Fork', bucket_fork_path(@bucket.token), class: 'btn btn-primary tm10', method: :post %>
@@ -0,0 +1,45 @@
1
+ <div class="panel-group request-show" id="accordion" role="tablist" aria-multiselectable="true">
2
+ <div class="panel panel-default">
3
+ <span class="pull-right label label-info" title="<%= recorded_request.created_at.utc %>"><%= time_ago_in_words recorded_request.created_at %> ago</span>
4
+ <div class="panel-heading" role="tab" id="headingOne">
5
+ <h4 class="panel-title">
6
+ <a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
7
+ Headers
8
+ </a>
9
+ </h4>
10
+ </div>
11
+ <div id="collapseOne" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingOne">
12
+ <div class="panel-body">
13
+ <pre><%= simple_format recorded_request.headers_as_string %></pre>
14
+ </div>
15
+ </div>
16
+ </div>
17
+ <div class="panel panel-default">
18
+ <div class="panel-heading" role="tab" id="headingTwo">
19
+ <h4 class="panel-title">
20
+ <a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="true" aria-controls="collapseTwo">
21
+ Request
22
+ </a>
23
+ </h4>
24
+ </div>
25
+ <div id="collapseTwo" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingTwo">
26
+ <div class="panel-body">
27
+ <pre><%= h recorded_request.body_as_string %></pre>
28
+ </div>
29
+ </div>
30
+ </div>
31
+ <div class="panel panel-default">
32
+ <div class="panel-heading" role="tab" id="headingThree">
33
+ <h4 class="panel-title">
34
+ <a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseThree" aria-expanded="true" aria-controls="collapseThree">
35
+ Response
36
+ </a>
37
+ </h4>
38
+ </div>
39
+ <div id="collapseThree" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingThree">
40
+ <div class="panel-body">
41
+ <pre><%= h recorded_request.response.body_as_string %></pre>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ </div>
@@ -0,0 +1,58 @@
1
+ <% content_for :title, @bucket.name %>
2
+
3
+ <ul class="nav">
4
+ <li class="logo"><a href="/"><%= image_tag 'logo.png' %></a></li>
5
+ <li><a href="<%= "/#{@bucket.token}/inspect" %>">Inspect</a></li>
6
+ <li><a href="<%= "/#{@bucket.token}/last" %>" title="JSON-formatted">Last Request</a></li>
7
+ <li><a href="<%= "/#{@bucket.token}/last_response" %>" title="JSON-formatted">Last Response</a></li>
8
+ <% if user_signed_in? %>
9
+ <li><%= link_to 'Sign out', destroy_user_session_path, method: :delete %></li>
10
+ <% else %>
11
+ <li><%= link_to 'Sign in', new_user_session_path %></li>
12
+ <li><%= link_to 'Sign up', new_user_registration_path %></li>
13
+ <% end %>
14
+ </ul>
15
+
16
+ <section class="putsreq-url-box">
17
+ <h3>Your PutsReq URL</h3>
18
+ <div class="input-group putsreq-url">
19
+ <input id="putsreq-url-input" data-bucket-token="<%= @bucket.token %>" type="text" value="<%= token_url(@bucket.token) %>" readonly="readonly"></input>
20
+ <span id="copy-button" class="input-group-addon hastip clipboard" data-clipboard-target="#putsreq-url-input">
21
+ <span class="glyphicon glyphicon-link hastip"></span>
22
+ </span>
23
+ </div>
24
+ </section>
25
+
26
+ <br/><br/>
27
+
28
+ <section>
29
+ <h4>Sample Request using cURL</h4>
30
+ <code>curl -i -X POST -d 'name=Pablo' <%= token_url(@bucket.token) %></code>
31
+ </section>
32
+
33
+ <hr/>
34
+ <%= render 'form' %>
35
+ <hr/>
36
+
37
+ <p id="new-requests-info"><!-- placeholder: New requests found. Load newer requests? --></p>
38
+
39
+ <div class="row">
40
+ <div class="col-md-6">
41
+ <% if @bucket.first_request_at %>
42
+ <p>
43
+ <em>First request at: <%= @bucket.first_request_at %></br>
44
+ Last request at: <%= @bucket.last_request_at %></br>
45
+ <% if @bucket.last_request_at - @bucket.first_request_at > 0 %>
46
+ From first to last: <%= distance_of_time_in_words @bucket.first_request_at, @bucket.last_request_at, include_seconds: true %>
47
+ <% end %>
48
+ </em>
49
+ </p>
50
+ <% end %>
51
+ </div>
52
+ <div class="col-md-6"></div>
53
+ </div>
54
+ <p><%= paginate @requests %></p>
55
+ <%= render(partial: 'requests', collection: @requests, as: :recorded_request) || show_no_requests_found(@bucket) %>
56
+ <p><%= paginate @requests %></p>
57
+
58
+ <script src="//js.pusher.com/2.2/pusher.min.js" type="text/javascript"></script>
@@ -0,0 +1,45 @@
1
+ <div class="row">
2
+ <div class="span10">
3
+ <div class="">
4
+ <header>
5
+ <%= image_tag 'logo.png' %>
6
+ <h3><em>PutsReq</em> lets you record HTTP requests and simulate responses like no other tool available. Try it now!</h3>
7
+ <%= form_for :bucket, url: buckets_path do |f| %>
8
+ <button class="btn btn-primary btn-large">Create a PutsReq</button>
9
+ <em>
10
+ <% if user_signed_in? %>
11
+ <%= link_to 'Sign out', destroy_user_session_path, method: :delete %>
12
+ <% else %>
13
+ <%= link_to 'Sign in', new_user_session_path %> | <%= link_to 'Sign up', new_user_registration_path %>
14
+ <% end %>
15
+ </em>
16
+ <% end %>
17
+ </header>
18
+ <section class="start">
19
+ <% if @buckets.any? %>
20
+ <div class="history">
21
+ <h4 class="bm0 tm0">History</h4>
22
+ <small>View and manage your buckets:</small>
23
+ <ul class="tm5">
24
+ <% @buckets.each do |bucket| %>
25
+ <li><%= link_to "#{bucket.name} (#{bucket.requests_count})", bucket_path(bucket.token) %></li>
26
+ <% end %>
27
+ </ul>
28
+ </div>
29
+ <% end %>
30
+ <h4>Record the requests sent or received</h4>
31
+ <p>Change your target URL to a PutsReq URL, then you will be able to inspect all headers and body being sent.
32
+ You can also debug callbacks from external services by configuring a PutsReq URL instead of your Webhook URL.</p>
33
+ <h4 class="tm20">Simulate responses</h4>
34
+ <p>PutsReq is the easiest way to simulate/stub HTTP responses. You can define the response status, headers and body with JavaScript using the <a href="https://github.com/phstc/putsreq#response-builder">Response Builder</a>.
35
+ If you don't want to test against the real API, but you know how to simulate (mock) the response, you can do that using a Response Builder.</p>
36
+ <p>Some use cases:</p>
37
+ <ul>
38
+ <li>Get the real response once then create a Response Builder simulating it and use PutsReq for the next calls.</li>
39
+ <li>Use PutsReq for your integration tests to verify if your application is making the HTTP requests as expected <a href="https://github.com/phstc/putsreq_integration_sample/blob/master/spec/acceptance/create_user_spec.rb">by checking the last recorded request</a>.</li>
40
+ <li>To benchmark by checking the First and Last request timestamps, or by checking the numbers of requests made within a period.</li>
41
+ </ul>
42
+ </section>
43
+ </div>
44
+ </div>
45
+ </div>
@@ -0,0 +1,18 @@
1
+ <title><%= content_for?(:title) ? yield(:title) : 'PutsReq' %></title>
2
+
3
+ <link rel="apple-touch-icon-precomposed" href="/images/favicon152.png" />
4
+ <link rel="icon" href="/images/favicon.png" />
5
+ <meta name="msapplication-TileColor" content="#ffffff" />
6
+ <meta name="msapplication-TileImage" content="/images/favicon144.png" />
7
+ <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
8
+ <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
9
+ <%= csrf_meta_tags %>
10
+ <script>
11
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
12
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
13
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
14
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
15
+
16
+ ga('create', 'UA-50754009-1', 'auto');
17
+ ga('send', 'pageview');
18
+ </script>