The duplication this app's spec suite already has
Five files, the same assertion, typed by hand each time
spec/requests/execution_spec.rb:
it "requires login" do
post execution_api_v1_sandbox_execute_path, params: { challenge_id: challenge.id, code_body: passing_code }
expect(response).to redirect_to(auth_sign_in_path)
end
spec/requests/catalog_spec.rb:
context "when guest" do
it "redirects to sign in" do
get catalog_course_path(course.slug)
expect(response).to redirect_to(auth_sign_in_path)
end
end
spec/requests/application_spec.rb:
it "redirects to sign in when login is required" do
get dashboard_path
expect(response).to redirect_to(auth_sign_in_path)
end
spec/requests/identity/user_preferences_spec.rb:
context "when user is not signed in" do
before do
delete auth_sign_in_path
end
it "redirects to the sign in page" do
patch identity_user_preferences_path, params: {
user_preference: { has_seen_welcome_modal: true }
}
expect(response).to redirect_to(auth_sign_in_path)
end
end
spec/requests/execution/solutions_spec.rb:
it "requires login" do
reveal!
expect(response).to redirect_to(auth_sign_in_path)
end
Those are five files, each read directly. The endpoint under test is different every time: a sandbox execute, a course page, the dashboard, a preferences update, a solution reveal. The arrange step is different every time too. But the last line of each example is the same assertion, expect(response).to redirect_to(auth_sign_in_path), typed out by hand in five separate files by whoever wrote each spec. Ten files under spec/requests/ contain that line today; these five show the pattern most plainly.
What's being duplicated
It isn't the whole test. It's one reusable fact about this app: an unauthenticated request to a page that requires login gets redirected to the sign-in page. That fact doesn't change from controller to controller. It's a property of this app's authentication guard, applied the same way everywhere it's used. Five files each rediscovered and re-asserted the same fact on their own, instead of stating it once and reusing it.
This app doesn't use RSpec's tool for this problem
RSpec ships a built-in mechanism for this shape of duplication: shared_examples, it_behaves_like and include_examples. A search of this app's spec suite for shared_examples or it_behaves_like comes back empty. The only related line is a default setting in spec/spec_helper.rb, config.shared_context_metadata_behavior = :apply_to_host_groups, and nothing uses it. The suite has never used the tool RSpec built for this situation, even though the situation exists in at least the five files above.
What this course covers
Seven lessons, each checked against RSpec's installed source and this app's spec files. Lesson 2 covers the shared_examples block itself: what it stores and where it can be looked up from. Lesson 3 covers it_behaves_like, which creates a nested example group, read from RSpec's source. Lesson 4 covers include_examples, which does the opposite and includes the same content flat in the current group. Lesson 5 covers passing arguments and a customization block into a shared example, shown on a second duplication this app's admin-only routes already have. Lesson 6 surveys where this app's suite would benefit. Lesson 7 ends with a small, plain-Ruby challenge that builds a miniature of shared_examples and it_behaves_like from scratch.
Keep going with lesson 2
shared_examples defines reusable spec content once
shared_examples stores a named block for later evaluation, with scoping rules and two aliases for the same method.
A free account also gives you the quizzes, your progress and notes, and the discussion.