29th / personnel-v3

Personnel management system version 3
https://www.29th.org
2 stars 6 forks source link

Add basic CRUD tests for management pages #209

Open wilson29thid opened 8 months ago

wilson29thid commented 8 months ago

Idea: Create a single ActiveAdmin controller test file which tests all pages of a list of resources. Use factories to generate attributes for creating and editing resources. These can then be supplemented by specific controller tests to test functionality beyond the basic CRUD stuff.

wilson29thid commented 8 months ago

I've got a basic implementation working, though it seems to break quite a few classes, e.g. ones with before-/after-save callbacks.

require "test_helper"

class Manage::ControllerTest < ActionDispatch::IntegrationTest
  namespace = ActiveAdmin.application.default_namespace
  resources = ActiveAdmin.application.namespaces[namespace].resources
    .filter { |r| r.instance_of?(ActiveAdmin::Resource) }

  resources.each do |resource|
    resource_name = resource.resource_name
    resource_title = resource_name.singular
    has_factory = FactoryBot.factories.any? { |f| f.name.to_s == resource_name.singular }
    actions = resource.defined_actions

    setup do
      @user = create(:user)
      @unit = create(:unit)
      create(:permission, abbr: "admin", unit: @unit)
      create(:assignment, user: @user, unit: @unit)
      sign_in_as @user

      @instance = create(resource_name.singular) if has_factory
    end

    if actions.include?(:index)
      test "#{resource_title} should get index" do
        get resource.route_collection_path
        assert_response :success
      end
    end

    if actions.include?(:show) && has_factory
      test "#{resource_title} should show" do
        get resource.route_instance_path(@instance)
        assert_response :success
      end
    end

    if actions.include?(:new)
      test "#{resource_title} should get new" do
        get resource.route_collection_path(:new)
        assert_response :success
      end
    end

    if actions.include?(:create) && has_factory
      test "#{resource_title} should create" do
        params = {}
        params[resource_title] = build(resource_name.singular).attributes.symbolize_keys

        assert_difference("#{resource.resource_class}.count", 1) do
          post resource.route_collection_path, params: params
        end

        assert_redirected_to resource.route_instance_path(resource.resource_class.last)
      end
    end

    if actions.include?(:edit) && has_factory
      test "#{resource_title} should get edit" do
        get resource.route_edit_instance_path(@instance)
        assert_response :success
      end
    end

    if actions.include?(:update) && has_factory
      test "#{resource_title} should update" do
        params = {}
        params[resource_title] = @instance.attributes.symbolize_keys
        instance_path = resource.route_instance_path(@instance)
        patch instance_path, params: params
        assert_redirected_to instance_path
      end
    end

    if actions.include?(:destroy) && has_factory
      test "#{resource_title} should destroy" do
        assert_difference("#{resource.resource_class}.count", -1) do
          delete resource.route_instance_path(@instance)
        end

        assert_redirected_to resource.route_collection_path
      end
    end
  end
end