putsreq 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.
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>