|
shared_examples_for "a secure v1 api" do |endpoints| |
|
endpoints.each do |endpoint| |
|
endpoint.each do |action, data| |
|
http_method = data[:request] || :get |
|
roles = data[:roles] || [] |
|
roles << 'admin' |
|
parameters = (data[:with] || {}).merge(format: 'json') |
|
|
|
describe "#{http_method}: #{action}" do |
|
User::ROLES.each do |role| |
|
expected_response = roles.include?(role) ? "success" : "failure" |
|
|
|
it "returns #{expected_response} for #{role}" do |
|
user = FactoryGirl.create(:user, role.to_sym) |
|
token = FactoryGirl.create(:doorkeeper_access_token, resource_owner_id: user.id) |
|
|
|
parameters.merge!({ access_token: token.token }) |
|
allow(subject).to receive(action) { subject.render nothing: true, status: 200 } |
|
self.send(http_method, action, parameters) |
|
|
|
if roles.include?(role) |
|
expect(response).to be_success, "#{http_method} #{action} when authorized as '#{role}' response was #{response.status}" |
|
else |
|
expect(response).to_not be_success, "#{http_method} #{action} when NOT authorized (logged in as '#{role}') response was #{response.status}" |
|
end |
|
end |
|
end |
|
|
|
it "returns 401 when not authenticated" do |
|
self.send(http_method, action, parameters) |
|
expect(response.response_code).to eq(401) |
|
end |
|
end |
|
end |
|
end |
|
end |
|
|
|
|
|
# Usage |
|
describe Api::V1::SomeController do |
|
describe "Security" do |
|
it_should_behave_like "a secure v1 api", [{ |
|
update: { roles: ['hr'], request: :put, with: { id: 1 } }, |
|
create: { roles: ['hr'], request: :post }, |
|
show: { roles: ['hr', 'employee'], with: { id: 1 } }, |
|
index: { roles: ['hr', 'employee'] } |
|
}] |
|
end |
|
end |