putsreq 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. checksums.yaml +5 -5
  2. data/.babelrc +26 -0
  3. data/.codeclimate.yml +29 -5
  4. data/.env.docker +6 -0
  5. data/.eslintignore +4 -0
  6. data/.eslintrc +22 -0
  7. data/.gitignore +8 -0
  8. data/.postcssrc.yml +3 -0
  9. data/.prettierrc +4 -0
  10. data/.reek +12 -0
  11. data/.rubocop.yml +47 -25
  12. data/.ruby-version +1 -1
  13. data/.simplecov +6 -0
  14. data/.travis.yml +38 -4
  15. data/Dockerfile +44 -0
  16. data/Gemfile +40 -61
  17. data/Gemfile.lock +294 -186
  18. data/Procfile +1 -1
  19. data/README.md +51 -46
  20. data/Rakefile +1 -1
  21. data/{public → app/assets}/images/logo.png +0 -0
  22. data/app/assets/javascripts/application.js +1 -1
  23. data/app/assets/javascripts/buckets.js.coffee +1 -21
  24. data/app/assets/stylesheets/{application.css → application.scss} +2 -1
  25. data/app/assets/stylesheets/buckets.css.scss +0 -2
  26. data/app/controllers/application_controller.rb +11 -9
  27. data/app/controllers/buckets_controller.rb +24 -18
  28. data/app/controllers/home_controller.rb +5 -5
  29. data/app/controllers/requests_controller.rb +13 -2
  30. data/app/helpers/application_helper.rb +6 -2
  31. data/app/interactors/create_or_retrieve_bucket.rb +17 -0
  32. data/app/interactors/create_request.rb +25 -7
  33. data/app/interactors/eval_response_builder.rb +9 -9
  34. data/app/interactors/filter_headers.rb +3 -3
  35. data/app/interactors/forward_request.rb +4 -4
  36. data/app/interactors/record_request.rb +1 -1
  37. data/app/interactors/track.rb +44 -0
  38. data/app/javascript/actionTypes.js +7 -0
  39. data/app/javascript/actions/index.js +64 -0
  40. data/app/javascript/components/Bucket.jsx +91 -0
  41. data/app/javascript/components/Pagination.jsx +67 -0
  42. data/app/javascript/components/RequestCount.jsx +21 -0
  43. data/app/javascript/components/request/Header.jsx +31 -0
  44. data/app/javascript/components/request/Response.jsx +28 -0
  45. data/app/javascript/components/request/index.jsx +47 -0
  46. data/app/javascript/packs/application.js +25 -0
  47. data/app/javascript/packs/hello_react.jsx +26 -0
  48. data/app/javascript/reducers/index.js +23 -0
  49. data/app/javascript/request_poller.js +19 -0
  50. data/app/javascript/store.js +9 -0
  51. data/app/models/bucket.rb +16 -10
  52. data/app/models/request.rb +2 -3
  53. data/app/models/user.rb +2 -2
  54. data/app/serializers/bucket_serializer.rb +11 -0
  55. data/app/serializers/request_serializer.rb +69 -0
  56. data/app/views/buckets/_buttons.html.erb +3 -3
  57. data/app/views/buckets/_form.html.erb +6 -6
  58. data/app/views/buckets/_readonly_buttons.html.erb +1 -1
  59. data/app/views/buckets/show.html.erb +12 -25
  60. data/app/views/home/index.html.erb +22 -16
  61. data/app/views/layouts/application.html.erb +21 -22
  62. data/app/views/layouts/devise.html.erb +16 -18
  63. data/app/views/shared/_flash.html.erb +3 -1
  64. data/bin/byebug +21 -0
  65. data/bin/cc-tddium-post-worker +21 -0
  66. data/bin/codeclimate-test-reporter +21 -0
  67. data/bin/coderay +21 -0
  68. data/bin/dotenv +21 -0
  69. data/bin/htmldiff +21 -0
  70. data/bin/httparty +21 -0
  71. data/bin/httpclient +21 -0
  72. data/bin/ldiff +21 -0
  73. data/bin/mongo_console +21 -0
  74. data/bin/nokogiri +21 -0
  75. data/bin/pry +21 -0
  76. data/bin/putsreq +18 -71
  77. data/bin/rackup +21 -0
  78. data/bin/rails +1 -1
  79. data/bin/ri +21 -0
  80. data/bin/rollbar-rails-runner +21 -0
  81. data/bin/rspec +10 -5
  82. data/bin/safe_yaml +21 -0
  83. data/bin/sass +21 -0
  84. data/bin/sass-convert +21 -0
  85. data/bin/scss +21 -0
  86. data/bin/sdoc +21 -0
  87. data/bin/sdoc-merge +21 -0
  88. data/bin/setup +38 -0
  89. data/bin/sprockets +21 -0
  90. data/bin/thor +21 -0
  91. data/bin/tilt +21 -0
  92. data/bin/unicorn +21 -0
  93. data/bin/unicorn_rails +21 -0
  94. data/bin/update +29 -0
  95. data/bin/webpack +15 -0
  96. data/bin/webpack-dev-server +15 -0
  97. data/bin/yarn +11 -0
  98. data/config/application.rb +6 -4
  99. data/config/boot.rb +1 -1
  100. data/config/environment.rb +1 -1
  101. data/config/environments/development.rb +7 -3
  102. data/config/environments/production.rb +5 -2
  103. data/config/environments/test.rb +3 -1
  104. data/config/initializers/devise.rb +2 -2
  105. data/config/initializers/rack_attack.rb +24 -0
  106. data/config/initializers/rollbar.rb +58 -0
  107. data/config/initializers/setup_email.rb +7 -7
  108. data/config/mongoid.yml +2 -2
  109. data/config/newrelic.yml +45 -0
  110. data/config/puma.rb +15 -0
  111. data/config/routes.rb +2 -0
  112. data/config/webpack/development.js +5 -0
  113. data/config/webpack/environment.js +3 -0
  114. data/config/webpack/production.js +5 -0
  115. data/config/webpack/test.js +5 -0
  116. data/config/webpacker.yml +70 -0
  117. data/docker-compose.yml +25 -0
  118. data/lib/putsreq/cli_helper.rb +114 -0
  119. data/lib/putsreq/version.rb +1 -1
  120. data/package.json +30 -0
  121. data/putsreq.gemspec +6 -7
  122. data/spec/controllers/buckets_controller_spec.rb +54 -46
  123. data/spec/interactors/create_or_retrieve_bucket_spec.rb +25 -0
  124. data/spec/interactors/create_request_spec.rb +11 -8
  125. data/spec/interactors/create_response_spec.rb +1 -1
  126. data/spec/interactors/eval_response_builder_spec.rb +14 -17
  127. data/spec/interactors/forward_request_spec.rb +4 -4
  128. data/spec/lib/putsreq/cli_helper_spec.rb +114 -0
  129. data/spec/models/bucket_spec.rb +3 -3
  130. data/spec/spec_helper.rb +25 -25
  131. data/yarn.lock +7043 -0
  132. metadata +85 -20
  133. data/.hound.yml +0 -14
  134. data/app/interactors/notify_count.rb +0 -15
  135. data/app/models/.keep +0 -0
  136. data/config/initializers/redis.rb +0 -17
  137. data/config/unicorn.rb +0 -16
  138. data/lib/assets/.keep +0 -0
  139. data/public/images/.keep +0 -0
  140. data/vendor/assets/javascripts/.keep +0 -0
  141. data/vendor/assets/stylesheets/.keep +0 -0
@@ -0,0 +1,5 @@
1
+ process.env.NODE_ENV = process.env.NODE_ENV || 'development'
2
+
3
+ const environment = require('./environment')
4
+
5
+ module.exports = environment.toWebpackConfig()
@@ -0,0 +1,3 @@
1
+ const { environment } = require('@rails/webpacker')
2
+
3
+ module.exports = environment
@@ -0,0 +1,5 @@
1
+ process.env.NODE_ENV = process.env.NODE_ENV || 'production'
2
+
3
+ const environment = require('./environment')
4
+
5
+ module.exports = environment.toWebpackConfig()
@@ -0,0 +1,5 @@
1
+ process.env.NODE_ENV = process.env.NODE_ENV || 'development'
2
+
3
+ const environment = require('./environment')
4
+
5
+ module.exports = environment.toWebpackConfig()
@@ -0,0 +1,70 @@
1
+ # Note: You must restart bin/webpack-dev-server for changes to take effect
2
+
3
+ default: &default
4
+ source_path: app/javascript
5
+ source_entry_path: packs
6
+ public_output_path: packs
7
+ cache_path: tmp/cache/webpacker
8
+ webpack_compile_output: false
9
+
10
+ # Additional paths webpack should lookup modules
11
+ # ['app/assets', 'engine/foo/app/assets']
12
+ resolved_paths: []
13
+
14
+ # Reload manifest.json on all requests so we reload latest compiled packs
15
+ cache_manifest: false
16
+
17
+ extensions:
18
+ - .jsx
19
+ - .js
20
+ - .sass
21
+ - .scss
22
+ - .css
23
+ - .module.sass
24
+ - .module.scss
25
+ - .module.css
26
+ - .png
27
+ - .svg
28
+ - .gif
29
+ - .jpeg
30
+ - .jpg
31
+
32
+ development:
33
+ <<: *default
34
+ compile: true
35
+
36
+ # Reference: https://webpack.js.org/configuration/dev-server/
37
+ dev_server:
38
+ https: false
39
+ host: localhost
40
+ port: 3035
41
+ public: localhost:3035
42
+ hmr: false
43
+ # Inline should be set to true if using HMR
44
+ inline: true
45
+ overlay: true
46
+ compress: true
47
+ disable_host_check: true
48
+ use_local_ip: false
49
+ quiet: false
50
+ headers:
51
+ 'Access-Control-Allow-Origin': '*'
52
+ watch_options:
53
+ ignored: '**/node_modules/**'
54
+
55
+
56
+ test:
57
+ <<: *default
58
+ compile: true
59
+
60
+ # Compile test packs to a separate directory
61
+ public_output_path: packs-test
62
+
63
+ production:
64
+ <<: *default
65
+
66
+ # Production depends on precompilation of packs prior to booting for performance.
67
+ compile: false
68
+
69
+ # Cache manifest.json for performance
70
+ cache_manifest: true
@@ -0,0 +1,25 @@
1
+ version: '3'
2
+ services:
3
+ db:
4
+ image: mongo:3.0.15-wheezy
5
+ volumes:
6
+ - ./tmp/db:/var/lib/mongo/data
7
+ redis:
8
+ image: redis:alpine
9
+ app:
10
+ build: .
11
+ tty: true
12
+ stdin_open: true
13
+ command: /bin/sh -c "rm -f /app/tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
14
+ volumes:
15
+ - .:/app
16
+ - node_modules:/app/node_modules
17
+ ports:
18
+ - '3000:3000'
19
+ env_file:
20
+ - .env.docker
21
+ depends_on:
22
+ - db
23
+ - redis
24
+ volumes:
25
+ node_modules:
@@ -0,0 +1,114 @@
1
+ module PutsReq
2
+ class CLIHelper
3
+ attr_reader :token, :to, :local
4
+
5
+ def initialize(token, to, local)
6
+ @token = token
7
+ @to = to
8
+ @local = local
9
+ end
10
+
11
+ def subscribe_and_forward
12
+ puts "Listening requests from #{token}"
13
+ puts "Forwarding to #{to}"
14
+ puts 'Press CTRL+c to terminate'
15
+
16
+ last_request_id = find_last_request_id
17
+
18
+ loop do
19
+ url = "#{base_url}#{token}/requests.json?last_request_id=#{last_request_id}"
20
+
21
+ response = get(url)
22
+
23
+ unless response.ok?
24
+ puts "Could not retrieve Bucket #{token}"
25
+ break
26
+ end
27
+
28
+ parsed_response = response.parsed_response
29
+
30
+ parsed_response.each do |request|
31
+ forward_request(request)
32
+ last_request_id = request.dig('_id', '$oid')
33
+ end
34
+
35
+ timeout = parsed_response.none? ? 5 : 2.5
36
+
37
+ sleep timeout
38
+ end
39
+ end
40
+
41
+ def find_and_forward(id)
42
+ if request = find_request(id)
43
+ forward_request(request)
44
+ else
45
+ puts "Request #{id} not found"
46
+ end
47
+ end
48
+
49
+ class << self
50
+ def parse_token(token)
51
+ if token.start_with? 'http'
52
+ # from http://putsreq.com/token or http://putsreq.com/token/inspect
53
+ # to token
54
+ uri = URI(token)
55
+ return uri.path.split('/')[1]
56
+ end
57
+
58
+ token
59
+ end
60
+
61
+ def valid_to?(to)
62
+ url = URI.parse(to) rescue nil
63
+ url&.kind_of?(URI::HTTP) || url&.kind_of?(URI::HTTPS)
64
+ end
65
+ end
66
+
67
+ private
68
+
69
+ def find_request(id)
70
+ url = "#{base_url}#{token}/requests/#{id}.json"
71
+ response = get(url)
72
+ response.parsed_response if response.ok?
73
+ end
74
+
75
+ def forward_request(request)
76
+ options = { headers: request['headers'] }
77
+ options[:body] = request['body'] unless request['body'].to_s.empty?
78
+
79
+ forward_request = HTTParty.send(
80
+ request['request_method'].downcase.to_sym,
81
+ to,
82
+ options
83
+ )
84
+
85
+ puts [
86
+ Time.now,
87
+ request['request_method'],
88
+ forward_request.code
89
+ ].join("\t")
90
+ end
91
+
92
+ def base_url
93
+ local ? 'http://localhost:3000/' : 'https://putsreq.com/'
94
+ end
95
+
96
+ def get(url, timeout = 5)
97
+ response = HTTParty.get(url)
98
+ if response.code == 429
99
+ puts 'Too Many Requests... Retrying soon'
100
+ timeout = [30, timeout + 5].min
101
+ sleep timeout
102
+ return get(url, timeout)
103
+ end
104
+
105
+ response
106
+ end
107
+
108
+ def find_last_request_id
109
+ url = "#{base_url}#{token}/last.json"
110
+ response = get(url)
111
+ response.parsed_response.dig('_id', '$oid') if response.ok?
112
+ end
113
+ end
114
+ end
@@ -1,3 +1,3 @@
1
1
  module PutsReq
2
- VERSION = '0.0.3'.freeze
2
+ VERSION = '0.0.4'.freeze
3
3
  end
@@ -0,0 +1,30 @@
1
+ {
2
+ "scripts": {
3
+ "prettier": "prettier --write app/{assets/javascripts,javascript}/**/*.{js,es6} --ignore-path=.gitignore"
4
+ },
5
+ "dependencies": {
6
+ "@rails/webpacker": "3.5",
7
+ "babel-preset-react": "^6.24.1",
8
+ "coffeescript": "1.12.7",
9
+ "cross-fetch": "~>1.1.1",
10
+ "lodash": "~> 4.17.5",
11
+ "prop-types": "^15.7.2",
12
+ "ramda-fantasy": "~>0.8.0",
13
+ "react": "^16.8.6",
14
+ "react-dom": "^16.8.6",
15
+ "react-redux": "~>5.0.7",
16
+ "redux": "~>3.7.2",
17
+ "redux-devtools-extension": "~>2.13.2",
18
+ "redux-thunk": "~>2.2.0",
19
+ "rxjs": "~>5.5.10"
20
+ },
21
+ "devDependencies": {
22
+ "cryptiles": ">=4.1.2",
23
+ "hoek": "~> 5.0.3",
24
+ "prettier": "1.12.1",
25
+ "ssri": "~>5.2.2",
26
+ "tar": ">=4.4.2",
27
+ "url-parse": ">=1.4.3",
28
+ "webpack-dev-server": "3.1.11"
29
+ }
30
+ }
@@ -1,5 +1,4 @@
1
- # -*- encoding: utf-8 -*-
2
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require 'putsreq/version'
5
4
 
@@ -8,15 +7,15 @@ Gem::Specification.new do |gem|
8
7
  gem.version = PutsReq::VERSION
9
8
  gem.authors = ['Pablo Cantero']
10
9
  gem.email = ['pablo@pablocantero.com']
11
- gem.description = %q{Ruby CLI for PutsReq}
12
- gem.summary = %q{Ruby CLI for PutsReq}
10
+ gem.description = 'Ruby CLI for PutsReq'
11
+ gem.summary = 'Ruby CLI for PutsReq'
13
12
  gem.homepage = 'https://github.com/phstc/putsreq'
14
13
 
15
- gem.files = `git ls-files`.split($/)
16
- gem.executables = %w(putsreq)
14
+ gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
15
+ gem.executables = %w[putsreq]
17
16
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
17
  gem.require_paths = ['lib']
19
18
 
20
- gem.add_dependency 'thor', '~> 0.19.3'
21
19
  gem.add_dependency 'pusher-client', '~> 0.6.2'
20
+ gem.add_dependency 'thor', '~> 0.19.3'
22
21
  end
@@ -11,20 +11,20 @@ RSpec.describe BucketsController, type: :controller do
11
11
  end
12
12
 
13
13
  describe 'DELETE #clear' do
14
- let(:rack_request) { ActionController::TestRequest.new('RAW_POST_DATA' => '{"message":"Hello World"}') }
14
+ let(:rack_request) { ActionController::TestRequest.create('RAW_POST_DATA' => '{"message":"Hello World"}') }
15
15
 
16
16
  before do
17
- stub_request(:get, 'http://example.com').
18
- to_return(body: '', status: 202, headers: { 'Content-Type' => 'text/plain' })
17
+ stub_request(:get, 'http://example.com')
18
+ .to_return(body: '', status: 202, headers: { 'Content-Type' => 'text/plain' })
19
19
  end
20
20
 
21
- it 'clears history' do
21
+ specify do
22
22
  RecordRequest.call(bucket: bucket, rack_request: rack_request)
23
23
 
24
24
  expect(bucket.requests.count).to eq(1)
25
25
  expect(bucket.responses.count).to eq(1)
26
26
 
27
- delete :clear, token: bucket.token
27
+ delete :clear, params: { token: bucket.token }
28
28
 
29
29
  bucket.reload
30
30
 
@@ -34,10 +34,10 @@ RSpec.describe BucketsController, type: :controller do
34
34
  end
35
35
 
36
36
  describe 'POST #fork' do
37
- it 'forks a bucket' do
37
+ specify do
38
38
  name = bucket.name
39
39
  expect {
40
- post :fork, token: bucket.token
40
+ post :fork, params: { token: bucket.token }
41
41
 
42
42
  expect(bucket.forks.count).to eq 1
43
43
 
@@ -52,10 +52,10 @@ RSpec.describe BucketsController, type: :controller do
52
52
  end
53
53
 
54
54
  describe 'PUT #update' do
55
- it 'updates a bucket' do
55
+ specify do
56
56
  bucket_params = { 'name' => 'test123', 'response_builder' => 'response.body = "ok";' }
57
57
 
58
- put :update, token: bucket.token, bucket: bucket_params
58
+ put :update, params: { token: bucket.token, bucket: bucket_params }
59
59
 
60
60
  bucket.reload
61
61
 
@@ -66,7 +66,7 @@ RSpec.describe BucketsController, type: :controller do
66
66
  end
67
67
 
68
68
  describe 'POST #create' do
69
- it 'creates a new bucket' do
69
+ specify do
70
70
  expect {
71
71
  post :create
72
72
  }.to change(Bucket, :count).by(1)
@@ -76,49 +76,55 @@ RSpec.describe BucketsController, type: :controller do
76
76
  end
77
77
 
78
78
  describe 'GET #show' do
79
- it 'shows a bucket' do
80
- get :show, token: bucket.token
79
+ specify do
80
+ get :show, params: { token: bucket.token }
81
81
 
82
- expect(assigns(:bucket)).to eq(bucket)
83
- expect(assigns(:requests).to_a).to eq(bucket.requests.to_a)
82
+ expect(assigns(:_bucket)).to eq(bucket)
84
83
  end
85
84
 
86
- it 'renders not found' do
87
- expect {
88
- get :show, token: '123'
89
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
85
+ context 'when not found' do
86
+ it 'creates a new bucket' do
87
+ token = 'not-found'
88
+ expect {
89
+ get :show, params: { token: token }
90
+
91
+ expect(assigns(:_bucket)).to eq(Bucket.find_by(token: token))
92
+ }.to change(Bucket, :count).by(1)
93
+ end
90
94
  end
91
95
  end
92
96
 
93
97
  describe 'GET #last' do
94
98
  context 'when found' do
95
- let(:rack_request) { ActionController::TestRequest.new('RAW_POST_DATA' => '{"message":"Hello World"}') }
99
+ context 'when JSON' do
100
+ let(:rack_request) { ActionController::TestRequest.create('RAW_POST_DATA' => '{"message":"Hello World"}') }
96
101
 
97
- before do
98
- stub_request(:get, 'http://example.com').
99
- to_return(body: '', status: 202, headers: { 'Content-Type' => 'text/plain' })
102
+ before do
103
+ stub_request(:get, 'http://example.com')
104
+ .to_return(body: '', status: 202, headers: { 'Content-Type' => 'text/plain' })
100
105
 
101
- RecordRequest.call(bucket: bucket, rack_request: rack_request)
102
- end
106
+ RecordRequest.call(bucket: bucket, rack_request: rack_request)
107
+ end
103
108
 
104
- it 'renders JSON' do
105
- get :last, token: bucket.token, format: :json
109
+ specify do
110
+ get :last, params: { token: bucket.token }, format: :json
106
111
 
107
- expect(response.body).to be_present # TODO: test the contents
108
- expect(response).to be_ok
112
+ expect(response.body).to be_present # TODO: test the contents
113
+ expect(response).to be_ok
114
+ end
109
115
  end
110
116
  end
111
117
 
112
118
  context 'when not found' do
113
- it 'redirects to root' do
114
- get :last, token: bucket.token
119
+ specify do
120
+ get :last, params: { token: bucket.token }
115
121
 
116
122
  expect(response).to redirect_to(bucket_path(bucket.token))
117
123
  end
118
124
 
119
125
  context 'when JSON' do
120
- it 'renders not_found' do
121
- get :last, token: bucket.token, format: :json
126
+ specify do
127
+ get :last, params: { token: bucket.token }, format: :json
122
128
 
123
129
  expect(response.status).to eq(404)
124
130
  end
@@ -128,33 +134,35 @@ RSpec.describe BucketsController, type: :controller do
128
134
 
129
135
  describe 'GET #last_response' do
130
136
  context 'when found' do
131
- let(:rack_request) { ActionController::TestRequest.new('RAW_POST_DATA' => '{"message":"Hello World"}') }
137
+ context 'when JSON' do
138
+ let(:rack_request) { ActionController::TestRequest.create('RAW_POST_DATA' => '{"message":"Hello World"}') }
132
139
 
133
- before do
134
- stub_request(:get, 'http://example.com').
135
- to_return(body: '', status: 202, headers: { 'Content-Type' => 'text/plain' })
140
+ before do
141
+ stub_request(:get, 'http://example.com')
142
+ .to_return(body: '', status: 202, headers: { 'Content-Type' => 'text/plain' })
136
143
 
137
- RecordRequest.call(bucket: bucket, rack_request: rack_request)
138
- end
144
+ RecordRequest.call(bucket: bucket, rack_request: rack_request)
145
+ end
139
146
 
140
- it 'renders JSON' do
141
- get :last_response, token: bucket.token, format: :json
147
+ specify do
148
+ get :last_response, params: { token: bucket.token }, format: :json
142
149
 
143
- expect(response.body).to be_present # TODO: test the contents
144
- expect(response).to be_ok
150
+ expect(response.body).to be
151
+ expect(response).to be_ok
152
+ end
145
153
  end
146
154
  end
147
155
 
148
156
  context 'when not found' do
149
- it 'redirects to root' do
150
- get :last_response, token: bucket.token
157
+ specify do
158
+ get :last_response, params: { token: bucket.token }
151
159
 
152
160
  expect(response).to redirect_to(bucket_path(bucket.token))
153
161
  end
154
162
 
155
163
  context 'when JSON' do
156
- it 'renders not_found' do
157
- get :last_response, token: bucket.token, format: :json
164
+ specify do
165
+ get :last_response, params: { token: bucket.token }, format: :json
158
166
 
159
167
  expect(response.status).to eq(404)
160
168
  end