# `AshGrant.PolicyTest`
[🔗](https://github.com/jhlee111/ash_grant/blob/v0.14.1/lib/ash_grant/policy_test.ex#L1)

DSL-based policy configuration testing for AshGrant.

This module provides a declarative way to test policy configurations
without requiring a database. It tests **policy configuration**, not data.

## Key Concept

| Traditional Unit Test | Policy Configuration Test |
|----------------------|--------------------------|
| Tests library behavior | Verifies user's policy setup |
| Requires DB records | No data needed |
| "Did Ash return right records?" | "Can actor X do action Y?" |
| `mix test` | `mix ash_grant.verify` |

## Usage

    defmodule MyApp.PolicyTests.DocumentPolicyTest do
      use AshGrant.PolicyTest

      resource MyApp.Document

      actor :reader, %{role: :reader}
      actor :author, %{role: :author, id: "author_001"}
      actor :guest, %{permissions: []}

      describe "read access" do
        test "reader can read" do
          assert_can :reader, :read
        end

        test "guest cannot read" do
          assert_cannot :guest, :read
        end

        test "reader can read published documents" do
          assert_can :reader, :read, %{status: :published}
        end
      end

      describe "update access" do
        test "author can update own drafts" do
          assert_can :author, :update, %{author_id: "author_001", status: :draft}
        end
      end
    end

## Action Specifiers

You can specify actions in several ways:

    assert_can :actor, :read                    # shorthand for action: :read
    assert_can :actor, action: :approve         # specific action name
    assert_can :actor, action_type: :update     # any action of this type

## Running Tests

    # Run all policy tests
    mix ash_grant.verify

    # Run specific file
    mix ash_grant.verify test/policy_tests/document_test.exs

    # Run with verbose output
    mix ash_grant.verify --verbose

# `__using__`
*macro* 

Sets up the PolicyTest DSL for a module.

When you `use AshGrant.PolicyTest`, it imports all the DSL macros
and sets up the module attributes needed to track resources, actors, and tests.

# `to_dsl`

```elixir
@spec to_dsl(String.t()) :: String.t()
```

Generates DSL code from a YAML file.

## Examples

    AshGrant.PolicyTest.to_dsl("priv/policy_tests/document.yaml")
    # => "defmodule DocumentPolicyTest do\n  use AshGrant.PolicyTest\n..."

# `to_yaml`

```elixir
@spec to_yaml(module()) :: String.t()
```

Converts a policy test module to YAML format.

## Examples

    AshGrant.PolicyTest.to_yaml(MyApp.PolicyTests.DocumentTest)
    # => "resource: MyApp.Document\nactors:\n  reader:\n    role: reader\n..."

---

*Consult [api-reference.md](api-reference.md) for complete listing*
