Skip to content

Commit 7e4188b

Browse files
committed
Add shared example for OpenAPI spec adherence
Honestly, i'm not sure if this is better than just having separate tests due to the extensive setup required in the before block. It might be that there's a better way to test this. Would def be good to get some feedback.
1 parent ce30d87 commit 7e4188b

1 file changed

Lines changed: 43 additions & 15 deletions

File tree

spec/requests/api/v0/conversations_spec.rb

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,40 @@
1919
end
2020
end
2121

22+
shared_examples "OpenAPI-compliant endpoint" do |path, method, field|
23+
let(:route_params) { {} }
24+
25+
context "when the response returned does not conform to the OpenAPI specification" do
26+
it "raises an error and returns the invalid params in the error message for #{path}" do
27+
expect { process(method.to_sym, public_send(path.to_sym, *route_params)) }
28+
.to raise_error(Committee::InvalidResponse) do |error|
29+
expect(error.message).to match(/missing required parameters: #{field}/)
30+
end
31+
end
32+
end
33+
end
34+
35+
2236
describe "GET :answer" do
2337
it_behaves_like "responds with forbidden if user doesn't have conversation-api permission",
2438
:api_v0_answer_question_path,
2539
:get do
2640
let(:route_params) { [create(:conversation), create(:question)] }
2741
end
42+
it_behaves_like "OpenAPI-compliant endpoint",
43+
:api_v0_answer_question_path,
44+
:get,
45+
:created_at do
46+
let(:question) { create(:question, :with_answer, conversation:) }
47+
let(:route_params) { [conversation, question] }
48+
49+
before do
50+
eager_loaded_answer = Answer.includes(:sources, :feedback).find(question.answer.id)
51+
answer_blueprint = AnswerBlueprint.render_as_hash(eager_loaded_answer)
52+
answer_blueprint.delete(:created_at)
53+
allow(AnswerBlueprint).to receive(:render).and_return(answer_blueprint)
54+
end
55+
end
2856

2957
context "when an answer has been generated for the question" do
3058
let!(:answer) { create(:answer, question:) }
@@ -63,21 +91,6 @@
6391
expect(JSON.parse(response.body)).to eq({})
6492
end
6593
end
66-
67-
context "when the response returned does not conform to the OpenAPI specification" do
68-
it "raises an error and returns the invalid params in the error message" do
69-
answer = create(:answer, question:)
70-
eager_loaded_answer = Answer.includes(:sources, :feedback).find(answer.id)
71-
answer_blueprint = AnswerBlueprint.render_as_hash(eager_loaded_answer)
72-
answer_blueprint.delete(:created_at)
73-
allow(AnswerBlueprint).to receive(:render).and_return(answer_blueprint)
74-
75-
expect { get api_v0_answer_question_path(conversation, question) }
76-
.to raise_error(Committee::InvalidResponse) do |error|
77-
expect(error.message).to match(/missing required parameters: created_at/)
78-
end
79-
end
80-
end
8194
end
8295

8396
describe "POST :answer_feedback" do
@@ -87,6 +100,21 @@
87100
let(:route_params) { [create(:conversation), create(:answer)] }
88101
end
89102

103+
it_behaves_like "OpenAPI-compliant endpoint",
104+
:api_v0_answer_feedback_path,
105+
:post,
106+
:fields do
107+
let(:answer) { create(:answer) }
108+
let(:route_params) { [answer.question.conversation, answer] }
109+
110+
before do
111+
answer = create(:answer, question:)
112+
error_blueprint = ValidationErrorBlueprint.render_as_hash(message: "Could not save answer feedback")
113+
error_blueprint.delete(:fields)
114+
allow(ValidationErrorBlueprint).to receive(:render).and_return(error_blueprint.as_json)
115+
end
116+
end
117+
90118
context "when the params are valid" do
91119
context "and the answer has no feedback" do
92120
let!(:answer) { create(:answer, question:) }

0 commit comments

Comments
 (0)