I am working on an api app that for this example has 2 basic user types, admin and user.
For this example the resource will be Widget. An admin has full access to a widget in the controller and a user has no access. Right now, I am repeating myself quite a bit when writing the request specs.
EG
require 'rails_helper'
RSpec.describe '/widgets', type: :request do
context 'with an admin user' do
let(:user) { create(:user, is_admin: true) }
let(:valid_attributes) { attributes_for(:widget) }
let(:invalid_attributes) { attributes_for(:widget, name: nil) }
let(:valid_headers) { Devise::JWT::TestHelpers.auth_headers({}, user) }
describe 'GET /widgets' do
it 'renders a successful response' do
create(:widget)
get widgets_url, headers: valid_headers, as: :json
expect(response).to be_successful
end
end
end
context 'with a standard user' do
let(:user) { create(:user) }
let(:valid_attributes) { attributes_for(:widget) }
let(:invalid_attributes) { attributes_for(:widget, name: nil) }
let(:valid_headers) { Devise::JWT::TestHelpers.auth_headers({}, user) }
describe 'GET /widgets' do
it 'renders an unauthorized response' do
create(:widget)
get widgets_url, headers: valid_headers, as: :json
expect(response).to have_http_status(403)
end
end
end
end
Now imagine this all done over the entire CRUD of the API and my request specs are 100s of lines long with a lot of copy pasting, they are hard to read and will be kind of difficult to manage.
Most of the boilerplate is the same, I am just wanting to implement different user contexts to verify that my policies are taking effect.
In a perfect world I would be able to define describe and context blocks once and then just make different expectations based on the user context.
Any suggestions on where to look?
you can pull up most of your
lets, as they are lazily evaluated anyway. e.g.:I would advisee against "DRYing" up further. Especially tests should be verbose about the functionality that they are ensuring.