Skip to content

Commit 5b4339c

Browse files
authored
Merge pull request #13 from pragmarb/no-response-error
NoResponseError
2 parents 163b363 + 2092328 commit 5b4339c

File tree

6 files changed

+85
-43
lines changed

6 files changed

+85
-43
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Started raising a `NoResponseError` if an operation doesn't return a `result.response` skill
13+
1014
## [2.2.0]
1115

1216
## Added

lib/pragma/rails.rb

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,12 @@
66
require 'pragma/rails/version'
77
require 'pragma/rails/controller'
88
require 'pragma/rails/resource_controller'
9+
require 'pragma/rails/errors'
910

1011
require 'generators/pragma/resource_generator' if defined?(::Rails::Generators)
1112

1213
module Pragma
1314
# Ruby on Rails integration for the Pragma architecture.
14-
#
15-
# @author Alessandro Desantis
1615
module Rails
1716
end
1817
end

lib/pragma/rails/controller.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ module Pragma
44
module Rails
55
# This mixin should be included in a Rails controller to provide integration with Pragma
66
# operations.
7-
#
8-
# @author Alessandro Desantis
97
module Controller
108
def self.included(klass)
119
klass.include InstanceMethods
@@ -28,6 +26,8 @@ def run(operation_klass)
2826
'policy.context' => policy_context
2927
)
3028

29+
fail NoResponseError unless result['result.response']
30+
3131
result['result.response'].headers.each_pair do |key, value|
3232
response.headers[key] = value
3333
end

lib/pragma/rails/errors.rb

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module Pragma
2+
module Rails
3+
class NoResponseError < StandardError
4+
def initialize
5+
super <<~MESSAGE
6+
Your operation did not return a `result.response` skill, which might mean one of the following:
7+
8+
* The execution of the operation halted early (maybe one of your steps returned a falsey value?).
9+
* You forgot to set a `result.response` skill in a custom operation.
10+
MESSAGE
11+
end
12+
end
13+
end
14+
end

lib/pragma/rails/resource_controller.rb

-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
module Pragma
44
module Rails
55
# Exposes CRUD operations on a resource through a Rails controller.
6-
#
7-
# @author Alessandro Desantis
86
module ResourceController
97
def self.included(klass)
108
klass.include Controller

spec/pragma/rails/controller_spec.rb

+64-37
Original file line numberDiff line numberDiff line change
@@ -5,56 +5,83 @@
55
RSpec.describe Pragma::Rails::Controller do
66
subject { controller_klass.new.tap(&:run_operation) }
77

8-
let(:controller_klass) do
9-
Class.new do
10-
attr_reader :render_args
11-
12-
def run_operation
13-
operation = Class.new(Pragma::Operation::Base) do
14-
step :respond!
15-
16-
def respond!(options, params:, **)
17-
options['result.response'] = Pragma::Operation::Response::Created.new(
18-
headers: { 'X-Foo' => params[:foo] },
19-
entity: { foo: params[:foo] }
20-
)
8+
context 'when the operation executes successfully' do
9+
let(:controller_klass) do
10+
Class.new do
11+
attr_reader :render_args
12+
13+
def run_operation
14+
operation = Class.new(Pragma::Operation::Base) do
15+
step :respond!
16+
17+
def respond!(options, params:, **)
18+
options['result.response'] = Pragma::Operation::Response::Created.new(
19+
headers: { 'X-Foo' => params[:foo] },
20+
entity: { foo: params[:foo] }
21+
)
22+
end
2123
end
24+
25+
run operation
2226
end
2327

24-
run operation
25-
end
28+
def response
29+
@response ||= OpenStruct.new(headers: {})
30+
end
2631

27-
def response
28-
@response ||= OpenStruct.new(headers: {})
29-
end
32+
def render(*args)
33+
@render_args = args
34+
end
3035

31-
def render(*args)
32-
@render_args = args
33-
end
36+
def params
37+
{}
38+
end
39+
40+
protected
3441

35-
def params
36-
{}
42+
def operation_params
43+
ActionController::Parameters.new(foo: 'bar')
44+
end
45+
end.tap do |klass|
46+
klass.include described_class
3747
end
48+
end
3849

39-
protected
50+
it 'responds with the headers from the operation' do
51+
expect(subject.response.headers).to eq('X-Foo' => 'bar')
52+
end
4053

41-
def operation_params
42-
ActionController::Parameters.new(foo: 'bar')
43-
end
44-
end.tap do |klass|
45-
klass.include described_class
54+
it 'responds with the status code from the operation' do
55+
expect(subject.render_args.first[:status]).to eq(201)
4656
end
47-
end
4857

49-
it 'responds with the headers from the operation' do
50-
expect(subject.response.headers).to eq('X-Foo' => 'bar')
58+
it 'responds with the resource from the operation' do
59+
expect(subject.render_args.first[:json]).to eq('foo' => 'bar')
60+
end
5161
end
5262

53-
it 'responds with the status code from the operation' do
54-
expect(subject.render_args.first[:status]).to eq(201)
55-
end
63+
context 'when the operation does not set a result.response skill' do
64+
let(:controller_klass) do
65+
Class.new do
66+
attr_reader :render_args
67+
68+
def run_operation
69+
operation = Class.new(Pragma::Operation::Base)
70+
run operation
71+
end
5672

57-
it 'responds with the resource from the operation' do
58-
expect(subject.render_args.first[:json]).to eq('foo' => 'bar')
73+
protected
74+
75+
def operation_params
76+
ActionController::Parameters.new(foo: 'bar')
77+
end
78+
end.tap do |klass|
79+
klass.include described_class
80+
end
81+
end
82+
83+
it 'raises a NoResponseError' do
84+
expect { subject }.to raise_error(Pragma::Rails::NoResponseError)
85+
end
5986
end
6087
end

0 commit comments

Comments
 (0)