update the classes from leave to leave record

This commit is contained in:
Tanmay Deep Sharma
2025-08-18 17:43:45 +05:30
parent 857c8d90d2
commit 5ce8533e9f
23 changed files with 781 additions and 1017 deletions
@@ -0,0 +1,315 @@
require 'rails_helper'
RSpec.describe 'LeaveRecords API', type: :request do
let(:account) { create(:account) }
let(:administrator) { create(:user, account: account, role: :administrator) }
let(:agent) { create(:user, account: account, role: :agent) }
let(:other_user) { create(:user, account: account, role: :agent) }
describe 'GET #index' do
let!(:agent_leave_record) { create(:leave_record, account: account, user: agent) }
let!(:other_user_leave_record) { create(:leave_record, account: account, user: other_user) }
context 'when authenticated as administrator' do
it 'returns all leave records in the account' do
get "/api/v1/accounts/#{account.id}/leave_records",
headers: administrator.create_new_auth_token
expect(response).to have_http_status(:success)
body = JSON.parse(response.body)
expect(body.length).to eq(2)
end
end
context 'when authenticated as agent' do
it 'returns only own leave records' do
get "/api/v1/accounts/#{account.id}/leave_records",
headers: agent.create_new_auth_token
expect(response).to have_http_status(:success)
body = JSON.parse(response.body)
expect(body.length).to eq(1)
expect(body[0]['user']['id']).to eq(agent.id)
end
end
context 'when unauthenticated' do
it 'returns unauthorized' do
get "/api/v1/accounts/#{account.id}/leave_records"
expect(response).to have_http_status(:unauthorized)
end
end
end
describe 'GET #show' do
let(:leave_record) { create(:leave_record, account: account, user: agent) }
let(:other_leave_record) { create(:leave_record, account: account, user: other_user) }
context 'when authenticated as administrator' do
it 'shows any leave record in the account' do
get "/api/v1/accounts/#{account.id}/leave_records/#{other_leave_record.id}",
headers: administrator.create_new_auth_token
expect(response).to have_http_status(:success)
body = JSON.parse(response.body)
expect(body['id']).to eq(other_leave_record.id)
expect(body['user']['id']).to eq(other_user.id)
end
end
context 'when authenticated as agent' do
it 'shows own leave record' do
get "/api/v1/accounts/#{account.id}/leave_records/#{leave_record.id}",
headers: agent.create_new_auth_token
expect(response).to have_http_status(:success)
body = JSON.parse(response.body)
expect(body['id']).to eq(leave_record.id)
expect(body['user']['id']).to eq(agent.id)
end
it 'denies access to other user leave record' do
get "/api/v1/accounts/#{account.id}/leave_records/#{other_leave_record.id}",
headers: agent.create_new_auth_token
expect(response).to have_http_status(:not_found)
end
end
end
describe 'POST #create' do
let(:valid_params) do
{
leave_record: {
start_date: 1.week.from_now.to_date,
end_date: 2.weeks.from_now.to_date,
leave_type: 'annual',
reason: 'Vacation time'
}
}
end
context 'when authenticated as agent' do
it 'creates a leave record for the current user' do
expect do
post "/api/v1/accounts/#{account.id}/leave_records",
params: valid_params,
headers: agent.create_new_auth_token
end.to change(LeaveRecord, :count).by(1)
expect(response).to have_http_status(:success)
body = JSON.parse(response.body)
expect(body['user']['id']).to eq(agent.id)
expect(body['leave_type']).to eq('annual')
expect(body['status']).to eq('pending')
end
it 'returns validation errors for invalid data' do
invalid_params = valid_params.deep_merge(
leave_record: { start_date: nil }
)
post "/api/v1/accounts/#{account.id}/leave_records",
params: invalid_params,
headers: agent.create_new_auth_token
expect(response).to have_http_status(:unprocessable_entity)
end
end
context 'when authenticated as administrator' do
it 'creates a leave record for the current user' do
expect do
post "/api/v1/accounts/#{account.id}/leave_records",
params: valid_params,
headers: administrator.create_new_auth_token
end.to change(LeaveRecord, :count).by(1)
expect(response).to have_http_status(:success)
body = JSON.parse(response.body)
expect(body['user']['id']).to eq(administrator.id)
end
end
end
describe 'PUT #update' do
let(:leave_record) { create(:leave_record, account: account, user: agent, status: :pending) }
let(:other_leave_record) { create(:leave_record, account: account, user: other_user, status: :pending) }
let(:update_params) do
{
leave_record: {
reason: 'Updated reason'
}
}
end
context 'when authenticated as administrator' do
it 'updates any pending leave record in the account' do
put "/api/v1/accounts/#{account.id}/leave_records/#{other_leave_record.id}",
params: update_params,
headers: administrator.create_new_auth_token
expect(response).to have_http_status(:success)
body = JSON.parse(response.body)
expect(body['reason']).to eq('Updated reason')
end
end
context 'when authenticated as agent' do
it 'updates own pending leave record' do
put "/api/v1/accounts/#{account.id}/leave_records/#{leave_record.id}",
params: update_params,
headers: agent.create_new_auth_token
expect(response).to have_http_status(:success)
body = JSON.parse(response.body)
expect(body['reason']).to eq('Updated reason')
end
it 'denies updating other user leave record' do
put "/api/v1/accounts/#{account.id}/leave_records/#{other_leave_record.id}",
params: update_params,
headers: agent.create_new_auth_token
expect(response).to have_http_status(:not_found)
end
it 'denies updating approved leave record' do
approved_leave_record = create(:leave_record, account: account, user: agent, status: :approved)
put "/api/v1/accounts/#{account.id}/leave_records/#{approved_leave_record.id}",
params: update_params,
headers: agent.create_new_auth_token
expect(response).to have_http_status(:not_found)
end
end
end
describe 'DELETE #destroy' do
let(:leave_record) { create(:leave_record, account: account, user: agent, status: :pending) }
let(:other_leave_record) { create(:leave_record, account: account, user: other_user, status: :pending) }
context 'when authenticated as administrator' do
it 'deletes any cancellable leave record in the account' do
expect do
delete "/api/v1/accounts/#{account.id}/leave_records/#{other_leave_record.id}",
headers: administrator.create_new_auth_token
end.to change(LeaveRecord, :count).by(-1)
expect(response).to have_http_status(:ok)
end
end
context 'when authenticated as agent' do
it 'deletes own cancellable leave record' do
expect do
delete "/api/v1/accounts/#{account.id}/leave_records/#{leave_record.id}",
headers: agent.create_new_auth_token
end.to change(LeaveRecord, :count).by(-1)
expect(response).to have_http_status(:ok)
end
it 'denies deleting other user leave record' do
delete "/api/v1/accounts/#{account.id}/leave_records/#{other_leave_record.id}",
headers: agent.create_new_auth_token
expect(response).to have_http_status(:not_found)
end
it 'denies deleting non-cancellable leave record' do
non_cancellable_leave_record = create(:leave_record, account: account, user: agent,
status: :approved,
start_date: Date.current,
end_date: Date.current + 2.days)
delete "/api/v1/accounts/#{account.id}/leave_records/#{non_cancellable_leave_record.id}",
headers: agent.create_new_auth_token
expect(response).to have_http_status(:not_found)
end
end
end
describe 'PATCH #approve' do
let(:leave_record) { create(:leave_record, account: account, user: agent, status: :pending) }
context 'when authenticated as administrator' do
it 'approves the leave record' do
patch "/api/v1/accounts/#{account.id}/leave_records/#{leave_record.id}/approve",
headers: administrator.create_new_auth_token
expect(response).to have_http_status(:success)
body = JSON.parse(response.body)
expect(body['status']).to eq('approved')
expect(body['approver']['id']).to eq(administrator.id)
end
end
context 'when authenticated as agent' do
it 'denies approval' do
patch "/api/v1/accounts/#{account.id}/leave_records/#{leave_record.id}/approve",
headers: agent.create_new_auth_token
expect(response).to have_http_status(:not_found)
end
end
end
describe 'PATCH #reject' do
let(:leave_record) { create(:leave_record, account: account, user: agent, status: :pending) }
context 'when authenticated as administrator' do
it 'rejects the leave record' do
patch "/api/v1/accounts/#{account.id}/leave_records/#{leave_record.id}/reject",
headers: administrator.create_new_auth_token
expect(response).to have_http_status(:success)
body = JSON.parse(response.body)
expect(body['status']).to eq('rejected')
expect(body['approver']['id']).to eq(administrator.id)
end
end
context 'when authenticated as agent' do
it 'denies rejection' do
patch "/api/v1/accounts/#{account.id}/leave_records/#{leave_record.id}/reject",
headers: agent.create_new_auth_token
expect(response).to have_http_status(:not_found)
end
end
end
describe 'response format' do
let(:leave_record) { create(:leave_record, account: account, user: agent) }
it 'returns leave record data in correct format' do
get "/api/v1/accounts/#{account.id}/leave_records/#{leave_record.id}",
headers: agent.create_new_auth_token
expect(response).to have_http_status(:success)
body = JSON.parse(response.body)
expect(body.keys).to include('id', 'start_date', 'end_date', 'leave_type', 'status',
'reason', 'duration_in_days', 'created_at', 'updated_at', 'user')
expect(body['user'].keys).to include('id', 'name', 'email')
end
it 'includes approver data when present' do
approved_leave_record = create(:leave_record, account: account, user: agent, status: :approved)
approved_leave_record.update!(approver: administrator, approved_at: Time.current)
get "/api/v1/accounts/#{account.id}/leave_records/#{approved_leave_record.id}",
headers: agent.create_new_auth_token
expect(response).to have_http_status(:success)
body = JSON.parse(response.body)
expect(body['approver']).not_to be_nil
expect(body['approver'].keys).to include('id', 'name', 'email')
end
end
end
@@ -1,550 +0,0 @@
require 'rails_helper'
RSpec.describe 'Leaves API', type: :request do
let(:account) { create(:account) }
let(:administrator) { create(:user, account: account, role: :administrator) }
let(:agent) { create(:user, account: account, role: :agent) }
let(:other_user) { create(:user, account: account, role: :agent) }
describe 'GET #index' do
before do
create(:leave, account: account, user: agent)
create(:leave, account: account, user: other_user)
end
context 'when authenticated as administrator' do
it 'returns all leaves in the account' do
get "/api/v1/accounts/#{account.id}/leaves",
headers: administrator.create_new_auth_token
expect(response).to have_http_status(:success)
body = JSON.parse(response.body)
expect(body['leaves'].length).to eq(2)
end
end
context 'when authenticated as agent' do
it 'returns only own leaves' do
get "/api/v1/accounts/#{account.id}/leaves",
headers: agent.create_new_auth_token
expect(response).to have_http_status(:success)
body = JSON.parse(response.body)
expect(body['leaves'].length).to eq(1)
expect(body['leaves'][0]['user']['id']).to eq(agent.id)
end
end
context 'when unauthenticated' do
it 'returns unauthorized' do
get "/api/v1/accounts/#{account.id}/leaves"
expect(response).to have_http_status(:unauthorized)
end
end
end
describe 'GET #show' do
let(:leave) { create(:leave, account: account, user: agent) }
let(:other_leave) { create(:leave, account: account, user: other_user) }
context 'when authenticated as administrator' do
it 'shows any leave in the account' do
get "/api/v1/accounts/#{account.id}/leaves/#{leave.id}",
headers: administrator.create_new_auth_token
expect(response).to have_http_status(:success)
body = JSON.parse(response.body)
expect(body['id']).to eq(leave.id)
end
end
context 'when authenticated as agent viewing own leave' do
it 'shows the leave' do
get "/api/v1/accounts/#{account.id}/leaves/#{leave.id}",
headers: agent.create_new_auth_token
expect(response).to have_http_status(:success)
body = JSON.parse(response.body)
expect(body['id']).to eq(leave.id)
expect(body['user']['id']).to eq(agent.id)
end
end
context 'when authenticated as agent viewing other user leave' do
it 'returns unauthorized' do
get "/api/v1/accounts/#{account.id}/leaves/#{other_leave.id}",
headers: agent.create_new_auth_token
expect(response).to have_http_status(:unauthorized)
end
end
context 'when leave does not exist' do
it 'returns not found' do
get "/api/v1/accounts/#{account.id}/leaves/99999",
headers: administrator.create_new_auth_token
expect(response).to have_http_status(:not_found)
end
end
context 'when unauthenticated' do
it 'returns unauthorized' do
get "/api/v1/accounts/#{account.id}/leaves/#{leave.id}"
expect(response).to have_http_status(:unauthorized)
end
end
end
describe 'POST #create' do
let(:valid_params) do
{
leave: {
start_date: 1.week.from_now.to_date,
end_date: 2.weeks.from_now.to_date,
leave_type: 'annual',
reason: 'Annual vacation'
}
}
end
context 'when authenticated as administrator' do
it 'creates a leave for current user' do
expect do
post "/api/v1/accounts/#{account.id}/leaves",
params: valid_params,
headers: administrator.create_new_auth_token
end.to change(Leave, :count).by(1)
expect(response).to have_http_status(:success)
body = JSON.parse(response.body)
expect(body['leave_type']).to eq('annual')
expect(body['user']['id']).to eq(administrator.id)
end
it 'creates leave with other type' do
params = valid_params.merge(leave: valid_params[:leave].merge(leave_type: 'other'))
post "/api/v1/accounts/#{account.id}/leaves",
params: params,
headers: administrator.create_new_auth_token
expect(response).to have_http_status(:success)
body = JSON.parse(response.body)
expect(body['leave_type']).to eq('other')
end
end
context 'when authenticated as agent' do
it 'creates a leave for current user' do
expect do
post "/api/v1/accounts/#{account.id}/leaves",
params: valid_params,
headers: agent.create_new_auth_token
end.to change(Leave, :count).by(1)
expect(response).to have_http_status(:success)
body = JSON.parse(response.body)
expect(body['user']['id']).to eq(agent.id)
end
end
context 'with invalid parameters' do
it 'returns validation errors for missing start date' do
invalid_params = valid_params.merge(leave: valid_params[:leave].except(:start_date))
post "/api/v1/accounts/#{account.id}/leaves",
params: invalid_params,
headers: agent.create_new_auth_token
expect(response).to have_http_status(:unprocessable_entity)
end
it 'returns validation errors for end date before start date' do
invalid_params = valid_params.merge(
leave: valid_params[:leave].merge(
start_date: 2.weeks.from_now.to_date,
end_date: 1.week.from_now.to_date
)
)
post "/api/v1/accounts/#{account.id}/leaves",
params: invalid_params,
headers: agent.create_new_auth_token
expect(response).to have_http_status(:unprocessable_entity)
end
it 'returns validation errors for past start date on pending leave' do
invalid_params = valid_params.merge(
leave: valid_params[:leave].merge(
start_date: 1.week.ago.to_date,
end_date: Date.current
)
)
post "/api/v1/accounts/#{account.id}/leaves",
params: invalid_params,
headers: agent.create_new_auth_token
expect(response).to have_http_status(:unprocessable_entity)
end
end
context 'when unauthenticated' do
it 'returns unauthorized' do
post "/api/v1/accounts/#{account.id}/leaves",
params: valid_params
expect(response).to have_http_status(:unauthorized)
end
end
end
describe 'PUT #update' do
let(:leave) { create(:leave, account: account, user: agent, status: :pending) }
let(:other_leave) { create(:leave, account: account, user: other_user, status: :pending) }
let(:approved_leave) { create(:leave, account: account, user: agent, status: :approved) }
let(:update_params) do
{
leave: {
reason: 'Updated reason'
}
}
end
context 'when authenticated as administrator' do
it 'updates any pending leave' do
put "/api/v1/accounts/#{account.id}/leaves/#{leave.id}",
params: update_params,
headers: administrator.create_new_auth_token
expect(response).to have_http_status(:success)
body = JSON.parse(response.body)
expect(body['reason']).to eq('Updated reason')
end
it 'cannot update non-pending leaves' do
put "/api/v1/accounts/#{account.id}/leaves/#{approved_leave.id}",
params: update_params,
headers: administrator.create_new_auth_token
expect(response).to have_http_status(:unauthorized)
end
end
context 'when authenticated as agent' do
it 'updates own pending leave' do
put "/api/v1/accounts/#{account.id}/leaves/#{leave.id}",
params: update_params,
headers: agent.create_new_auth_token
expect(response).to have_http_status(:success)
body = JSON.parse(response.body)
expect(body['reason']).to eq('Updated reason')
end
it 'cannot update other user leave' do
put "/api/v1/accounts/#{account.id}/leaves/#{other_leave.id}",
params: update_params,
headers: agent.create_new_auth_token
expect(response).to have_http_status(:unauthorized)
end
it 'cannot update non-pending leaves' do
put "/api/v1/accounts/#{account.id}/leaves/#{approved_leave.id}",
params: update_params,
headers: administrator.create_new_auth_token
expect(response).to have_http_status(:unauthorized)
end
end
context 'when leave does not exist' do
it 'returns not found' do
put "/api/v1/accounts/#{account.id}/leaves/99999",
params: update_params,
headers: administrator.create_new_auth_token
expect(response).to have_http_status(:not_found)
end
end
context 'when unauthenticated' do
it 'returns unauthorized' do
put "/api/v1/accounts/#{account.id}/leaves/#{leave.id}",
params: update_params
expect(response).to have_http_status(:unauthorized)
end
end
end
describe 'DELETE #destroy' do
let(:pending_leave) { create(:leave, account: account, user: agent, status: :pending) }
let(:approved_future_leave) do
create(:leave, account: account, user: agent, status: :approved,
start_date: 1.month.from_now.to_date, end_date: 1.month.from_now.to_date + 5.days)
end
let(:approved_past_leave) do
create(:leave, account: account, user: agent, status: :approved,
start_date: 1.week.ago.to_date, end_date: 3.days.ago.to_date)
end
let(:other_leave) { create(:leave, account: account, user: other_user, status: :pending) }
context 'when authenticated as administrator' do
it 'deletes cancellable leaves' do
expect do
delete "/api/v1/accounts/#{account.id}/leaves/#{pending_leave.id}",
headers: administrator.create_new_auth_token
end.to change(Leave, :count).by(-1)
expect(response).to have_http_status(:success)
end
it 'deletes approved future leaves' do
expect do
delete "/api/v1/accounts/#{account.id}/leaves/#{approved_future_leave.id}",
headers: administrator.create_new_auth_token
end.to change(Leave, :count).by(-1)
expect(response).to have_http_status(:success)
end
it 'cannot delete non-cancellable leaves' do
delete "/api/v1/accounts/#{account.id}/leaves/#{approved_past_leave.id}",
headers: administrator.create_new_auth_token
expect(response).to have_http_status(:unauthorized)
end
end
context 'when authenticated as agent' do
it 'deletes own cancellable leaves' do
expect do
delete "/api/v1/accounts/#{account.id}/leaves/#{pending_leave.id}",
headers: agent.create_new_auth_token
end.to change(Leave, :count).by(-1)
expect(response).to have_http_status(:success)
end
it 'cannot delete other user leaves' do
delete "/api/v1/accounts/#{account.id}/leaves/#{other_leave.id}",
headers: agent.create_new_auth_token
expect(response).to have_http_status(:unauthorized)
end
end
context 'when leave does not exist' do
it 'returns not found' do
delete "/api/v1/accounts/#{account.id}/leaves/99999",
headers: administrator.create_new_auth_token
expect(response).to have_http_status(:not_found)
end
end
context 'when unauthenticated' do
it 'returns unauthorized' do
delete "/api/v1/accounts/#{account.id}/leaves/#{pending_leave.id}"
expect(response).to have_http_status(:unauthorized)
end
end
end
describe 'PATCH #approve' do
let(:pending_leave) { create(:leave, account: account, user: agent, status: :pending) }
let(:approved_leave) { create(:leave, account: account, user: agent, status: :approved) }
context 'when authenticated as administrator' do
it 'approves pending leave' do
patch "/api/v1/accounts/#{account.id}/leaves/#{pending_leave.id}/approve",
headers: administrator.create_new_auth_token
expect(response).to have_http_status(:success)
body = JSON.parse(response.body)
expect(body['status']).to eq('approved')
expect(body['approver']['id']).to eq(administrator.id)
expect(body['approved_at']).not_to be_nil
pending_leave.reload
expect(pending_leave.status).to eq('approved')
expect(pending_leave.approver).to eq(administrator)
end
it 'updates approved_at timestamp' do
freeze_time = Time.current
allow(Time).to receive(:current).and_return(freeze_time)
patch "/api/v1/accounts/#{account.id}/leaves/#{pending_leave.id}/approve",
headers: administrator.create_new_auth_token
expect(response).to have_http_status(:success)
pending_leave.reload
expect(pending_leave.approved_at.to_i).to eq(freeze_time.to_i)
end
end
context 'when authenticated as agent' do
it 'returns unauthorized' do
patch "/api/v1/accounts/#{account.id}/leaves/#{pending_leave.id}/approve",
headers: agent.create_new_auth_token
expect(response).to have_http_status(:unauthorized)
end
end
context 'when leave does not exist' do
it 'returns not found' do
patch "/api/v1/accounts/#{account.id}/leaves/99999/approve",
headers: administrator.create_new_auth_token
expect(response).to have_http_status(:not_found)
end
end
context 'when unauthenticated' do
it 'returns unauthorized' do
patch "/api/v1/accounts/#{account.id}/leaves/#{pending_leave.id}/approve"
expect(response).to have_http_status(:unauthorized)
end
end
end
describe 'PATCH #reject' do
let(:pending_leave) { create(:leave, account: account, user: agent, status: :pending) }
let(:rejected_leave) { create(:leave, account: account, user: agent, status: :rejected) }
context 'when authenticated as administrator' do
it 'rejects pending leave' do
patch "/api/v1/accounts/#{account.id}/leaves/#{pending_leave.id}/reject",
headers: administrator.create_new_auth_token
expect(response).to have_http_status(:success)
body = JSON.parse(response.body)
expect(body['status']).to eq('rejected')
expect(body['approver']['id']).to eq(administrator.id)
expect(body['approved_at']).not_to be_nil
pending_leave.reload
expect(pending_leave.status).to eq('rejected')
expect(pending_leave.approver).to eq(administrator)
end
it 'updates approved_at timestamp on rejection' do
freeze_time = Time.current
allow(Time).to receive(:current).and_return(freeze_time)
patch "/api/v1/accounts/#{account.id}/leaves/#{pending_leave.id}/reject",
headers: administrator.create_new_auth_token
expect(response).to have_http_status(:success)
pending_leave.reload
expect(pending_leave.approved_at.to_i).to eq(freeze_time.to_i)
end
end
context 'when authenticated as agent' do
it 'returns unauthorized' do
patch "/api/v1/accounts/#{account.id}/leaves/#{pending_leave.id}/reject",
headers: agent.create_new_auth_token
expect(response).to have_http_status(:unauthorized)
end
end
context 'when leave does not exist' do
it 'returns not found' do
patch "/api/v1/accounts/#{account.id}/leaves/99999/reject",
headers: administrator.create_new_auth_token
expect(response).to have_http_status(:not_found)
end
end
context 'when unauthenticated' do
it 'returns unauthorized' do
patch "/api/v1/accounts/#{account.id}/leaves/#{pending_leave.id}/reject"
expect(response).to have_http_status(:unauthorized)
end
end
end
describe 'Business logic scenarios' do
describe 'leave overlap detection' do
let(:existing_leave) do
create(:leave, account: account, user: agent, status: :approved,
start_date: 1.month.from_now.to_date,
end_date: 1.month.from_now.to_date + 5.days)
end
it 'allows non-overlapping leaves' do
existing_leave
params = {
leave: {
start_date: 2.months.from_now.to_date,
end_date: 2.months.from_now.to_date + 3.days,
leave_type: 'annual',
reason: 'Second vacation'
}
}
post "/api/v1/accounts/#{account.id}/leaves",
params: params,
headers: agent.create_new_auth_token
expect(response).to have_http_status(:success)
end
end
describe 'leave duration calculation' do
it 'includes duration in response' do
params = {
leave: {
start_date: 1.week.from_now.to_date,
end_date: 1.week.from_now.to_date + 4.days,
leave_type: 'annual',
reason: 'Five day vacation'
}
}
post "/api/v1/accounts/#{account.id}/leaves",
params: params,
headers: agent.create_new_auth_token
expect(response).to have_http_status(:success)
body = JSON.parse(response.body)
expect(body['duration_in_days']).to eq(5)
end
end
describe 'approver validation' do
let(:non_admin_approver) { create(:user, account: account, role: :agent) }
before do
# Ensure approver is linked to account
create(:account_user, account: account, user: non_admin_approver, role: :agent)
create(:account_user, account: account, user: administrator, role: :administrator)
end
it 'rejects leave approval by non-administrator' do
leave = create(:leave, account: account, user: agent, status: :pending)
# Simulate manual update with non-admin approver (would fail validation)
expect do
leave.update!(approved_by_id: non_admin_approver.id, status: :approved)
end.to raise_error(ActiveRecord::RecordInvalid)
end
end
end
end