Skip to content

Commit b0e04e6

Browse files
Add not_found extension
This extension helps to build a not-found response in a single method invocation. The `WebPipe::Conn#not_found` method will: - Set 404 as response status. - Set 'Not found' as the response body, or instead run a step configured in `:not_found_body_step` config key. - Halt the connection struct. ```ruby require 'web_pipe' require 'web_pipe/plugs/config' WebPipe.load_extensions(:params, :not_found) class ShowItem include 'web_pipe' plug :config, WebPipe::Plugs::Config.( not_found_body_step: ->(conn) { conn.set_response_body('Nothing') } ) plug :fetch_item do |conn| conn.add(:item, Item[params['id']]) end plug :check_item do |conn| if conn.fetch(:item) conn else conn.not_found end end plug :render do |conn| conn.set_response_body(conn.fetch(:item).name) end end ```
1 parent 7a0364f commit b0e04e6

File tree

6 files changed

+150
-1
lines changed

6 files changed

+150
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ extension](docs/extensions/rails.md).
4141
1. [Flash](docs/extensions/flash.md)
4242
1. [Dry Schema](docs/extensions/dry_schema.md)
4343
1. [Hanami View](docs/extensions/hanami_view.md)
44+
1. [Not found](docs/extensions/not_found.md)
4445
1. [Params](docs/extensions/params.md)
4546
1. [Rails](docs/extensions/rails.md)
4647
1. [Redirect](docs/extensions/redirect.md)

docs/extensions/not_found.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Not found
2+
3+
This extension helps to build a not-found response in a single method
4+
invocation. The `WebPipe::Conn#not_found` method will:
5+
6+
- Set 404 as response status.
7+
- Set 'Not found' as the response body, or instead run a step configured in
8+
`:not_found_body_step` config key.
9+
- Halt the connection struct.
10+
11+
```ruby
12+
require 'web_pipe'
13+
require 'web_pipe/plugs/config'
14+
15+
WebPipe.load_extensions(:params, :not_found)
16+
17+
class ShowItem
18+
include 'web_pipe'
19+
20+
plug :config, WebPipe::Plugs::Config.(
21+
not_found_body_step: ->(conn) { conn.set_response_body('Nothing') }
22+
)
23+
24+
plug :fetch_item do |conn|
25+
conn.add(:item, Item[params['id']])
26+
end
27+
28+
plug :check_item do |conn|
29+
if conn.fetch(:item)
30+
conn
31+
else
32+
conn.not_found
33+
end
34+
end
35+
36+
plug :render do |conn|
37+
conn.set_response_body(conn.fetch(:item).name)
38+
end
39+
end
40+
```

lib/web_pipe.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,8 @@ def self.call(**opts)
6262
register_extension :url do
6363
require 'web_pipe/extensions/url/url'
6464
end
65+
66+
register_extension :not_found do
67+
require 'web_pipe/extensions/not_found/not_found'
68+
end
6569
end
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# frozen_string_literal: true
2+
3+
#:nodoc:
4+
module WebPipe
5+
# Generates a not-found response
6+
#
7+
# This extension helps to build a not-found response in a single method
8+
# invocation. The {#not_found} method will:
9+
#
10+
# - Set 404 as response status.
11+
# - Set 'Not found' as the response body, or instead run a step configured in
12+
# a `:not_found_body_step` config key.
13+
# - Halt the connection struct.
14+
#
15+
# @example
16+
# require 'web_pipe'
17+
# require 'web_pipe/plugs/config'
18+
#
19+
# WebPipe.load_extensions(:params, :not_found)
20+
#
21+
# class ShowItem
22+
# include 'web_pipe'
23+
#
24+
# plug :config, WebPipe::Plugs::Config.(
25+
# not_found_body_step: ->(conn) { conn.set_response_body('Nothing') }
26+
# )
27+
#
28+
# plug :fetch_item do |conn|
29+
# conn.add(:item, Item[params['id']])
30+
# end
31+
#
32+
# plug :check_item do |conn|
33+
# if conn.fetch(:item)
34+
# conn
35+
# else
36+
# conn.not_found
37+
# end
38+
# end
39+
#
40+
# plug :render do |conn|
41+
# conn.set_response_body(conn.fetch(:item).name)
42+
# end
43+
# end
44+
module NotFound
45+
# @api private
46+
RESPONSE_BODY_STEP_CONFIG_KEY = :not_found_body_step
47+
48+
# Generates the not-found response
49+
#
50+
# @return [WebPipe::Conn::Halted]
51+
# @see NotFound
52+
def not_found
53+
set_status(404)
54+
.then do |conn|
55+
response_body_step = conn.fetch_config(RESPONSE_BODY_STEP_CONFIG_KEY,
56+
->(c) { c.set_response_body('Not found') })
57+
58+
response_body_step.call(conn)
59+
end.halt
60+
end
61+
62+
Conn.include(NotFound)
63+
end
64+
end
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# frozen_string_literal: true
2+
3+
require 'spec_helper'
4+
require 'web_pipe'
5+
require 'support/conn'
6+
7+
RSpec.describe WebPipe::Conn do
8+
before { WebPipe.load_extensions(:not_found) }
9+
10+
describe '#not_found' do
11+
it 'sets 404 status code' do
12+
conn = build_conn
13+
14+
expect(conn.not_found.status).to be(404)
15+
end
16+
17+
it 'halts it' do
18+
conn = build_conn
19+
20+
expect(conn.not_found.halted?).to be(true)
21+
end
22+
23+
context 'when no response body is configured' do
24+
it 'sets "Not found" as response body' do
25+
conn = build_conn
26+
27+
expect(conn.not_found.response_body).to eq(['Not found'])
28+
end
29+
end
30+
31+
context 'when a step to build the response body is configured' do
32+
it 'uses it' do
33+
conn = build_conn.add_config(:not_found_body_step,
34+
->(c) { c.set_response_body('Nothing here') })
35+
36+
expect(conn.not_found.response_body).to eq(['Nothing here'])
37+
end
38+
end
39+
end
40+
end

spec/support/conn.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@ def default_env
2929
#
3030
# @param env [Hash]
3131
# @return Conn [WebPipe::Conn]
32-
def build_conn(env)
32+
def build_conn(env = default_env)
3333
WebPipe::ConnSupport::Builder.call(env)
3434
end

0 commit comments

Comments
 (0)