forked from activeadmin/activeadmin
-
Notifications
You must be signed in to change notification settings - Fork 0
Testing your ActiveAdmin controllers with RSpec
Lan edited this page Jul 23, 2020
·
9 revisions
The old content of this page was moved to Testing ActiveAdmin within another gem using RSpec and Combustion
app/models/person.rb
class Person < ApplicationRecord
validates :first_name, presence: true
end
app/admin/persons.rb
ActiveAdmin.register Person do
filter :first_name_or_last_name_cont, label: 'Name'
filter :email
index do
selectable_column
column :first_name
column :last_name
column :email
actions
end
show do
attributes_table do
row :first_name
row :last_name
row :email
end
end
permit_params :first_name,
:last_name,
:email
form do |f|
f.semantic_errors *f.object.errors.keys
f.inputs do
f.input :first_name
f.input :last_name
f.input :email
end
f.actions
end
end
You can find your controller classname by running this method call in a console (replacing :admin
with the namespace you're using):
ActiveAdmin.application.namespaces[:admin].resources.map(&:controller)
Assuming you use the following gems:
- rspec
- capybara
- shoulda-matchers
- fabrication
spec/controllers/admin/persons_controller_spec.rb
require 'rails_helper'
RSpec.describe Admin::PersonsController, type: :controller do
# this lets us inspect the rendered results
render_views
let(:page) { Capybara::Node::Simple.new(response.body) }
let(:user) { Fabricate :user }
before { sign_in user } # if `sign_in` method not exists, please check this document https://github.com/heartcombo/devise#controller-tests.
let!(:person) { Fabricate :person }
let(:valid_attributes) do
Fabricate.attributes_for :person
end
let(:invalid_attributes) do
{ first_name: '' }
end
describe "GET index" do
it 'returns http success' do
get :index
expect(response).to have_http_status(:success)
end
it 'assigns the person' do
get :index
expect(assigns(:persons)).to include(person)
end
it "should render the expected columns" do
get :index
expect(page).to have_content(person.first_name)
expect(page).to have_content(person.last_name)
expect(page).to have_content(person.email)
end
let(:filters_sidebar) { page.find('#filters_sidebar_section') }
it "filter Name exists" do
get :index
expect(filters_sidebar).to have_css('label[for="q_first_name_or_last_name_cont"]', text: 'Name')
expect(filters_sidebar).to have_css('input[name="q[first_name_or_last_name_cont]"]')
end
it "filter Name works" do
matching_person = Fabricate :person, first_name: 'ABCDEFG'
non_matching_person = Fabricate :person, first_name: 'HIJKLMN'
get :index, params: { q: { first_name_or_last_name_cont: 'BCDEF' } }
expect(assigns(:persons)).to include(matching_person)
expect(assigns(:persons)).not_to include(non_matching_person)
end
end
describe "GET new" do
it 'returns http success' do
get :new
expect(response).to have_http_status(:success)
end
it 'assigns the person' do
get :new
expect(assigns(:person)).to be_a_new(Person)
end
it "should render the form elements" do
get :new
expect(page).to have_field('First name')
expect(page).to have_field('Last name')
expect(page).to have_field('Email')
end
end
describe "POST create" do
context "with valid params" do
it "creates a new Person" do
expect {
post :create, params: { person: valid_attributes }
}.to change(Person, :count).by(1)
end
it "assigns a newly created person as @person" do
post :create, params: { person: valid_attributes }
expect(assigns(:person)).to be_a(Person)
expect(assigns(:person)).to be_persisted
end
it "redirects to the created person" do
post :create, params: { person: valid_attributes }
expect(response).to have_http_status(:redirect)
expect(response).to redirect_to(admin_person_path(Person.last))
end
it 'should create the person' do
post :create, params: { person: valid_attributes }
person = Person.last
expect(person.first_name).to eq(valid_attributes[:first_name])
expect(person.last_name).to eq(valid_attributes[:last_name])
expect(person.email).to eq(valid_attributes[:email])
end
end
context "with invalid params" do
it 'invalid_attributes return http success' do
post :create, params: { person: invalid_attributes }
expect(response).to have_http_status(:success)
end
it "assigns a newly created but unsaved person as @person" do
post :create, params: { person: invalid_attributes }
expect(assigns(:person)).to be_a_new(Person)
end
it 'invalid_attributes do not create a Person' do
expect do
post :create, params: { person: invalid_attributes }
end.not_to change(Person, :count)
end
end
end
describe "GET edit" do
before do
get :edit, params: { id: person.id }
end
it 'returns http success' do
expect(response).to have_http_status(:success)
end
it 'assigns the person' do
expect(assigns(:person)).to eq(person)
end
it "should render the form elements" do
expect(page).to have_field('First name', with: person.first_name)
expect(page).to have_field('Last name', with: person.last_name)
expect(page).to have_field('Email', with: person.email)
end
end
describe "PUT update" do
context 'with valid params' do
before do
put :update, params: { id: person.id, person: valid_attributes }
end
it 'assigns the person' do
expect(assigns(:person)).to eq(person)
end
it 'returns http redirect' do
expect(response).to have_http_status(:redirect)
expect(response).to redirect_to(admin_person_path(person))
end
it "should update the person" do
person.reload
expect(person.last_name).to eq(valid_attributes[:last_name])
expect(person.first_name).to eq(valid_attributes[:first_name])
expect(person.email).to eq(valid_attributes[:email])
end
end
context 'with invalid params' do
it 'returns http success' do
put :update, params: { id: person.id, person: invalid_attributes }
expect(response).to have_http_status(:success)
end
it 'does not change person' do
expect do
put :update, params: { id: person.id, person: invalid_attributes }
end.not_to change { person.reload.first_name }
end
end
end
describe "GET show" do
before do
get :show, params: { id: person.id }
end
it 'returns http success' do
expect(response).to have_http_status(:success)
end
it 'assigns the person' do
expect(assigns(:person)).to eq(person)
end
it "should render the form elements" do
expect(page).to have_content(person.last_name)
expect(page).to have_content(person.first_name)
expect(page).to have_content(person.email)
end
end
describe "DELETE #destroy" do
it "destroys the requested select_option" do
expect {
delete :destroy, params: { id: person.id }
}.to change(Person, :count).by(-1)
end
it "redirects to the field" do
delete :destroy, params: { id: person.id }
expect(response).to redirect_to(admin_persons_path)
end
end
end