import { test } from '@japa/runner'
import { MatchResourceOwnerAccessRule } from '../../../../src/modeling/rules/MatchResourceOwner.js'

test.group('MatchResourceOwnerAccessRule', () => {
  test('initializes with default values', ({ assert }) => {
    const rule = new MatchResourceOwnerAccessRule()
    assert.equal(rule.type, 'matchResourceOwner')
    assert.isUndefined(rule.property)
    assert.equal(rule.target, 'property')
  }).tags(['@modeling', '@rule', '@match-resource-owner'])

  test('initializes with provided values', ({ assert }) => {
    const rule = new MatchResourceOwnerAccessRule({ property: 'creatorId' })

    assert.equal(rule.type, 'matchResourceOwner')
    assert.equal(rule.property, 'creatorId')
    assert.equal(rule.target, 'property')
  }).tags(['@modeling', '@rule', '@match-resource-owner'])

  test('initializes with target user-entity', ({ assert }) => {
    const rule = new MatchResourceOwnerAccessRule({ target: 'user-entity' })

    assert.equal(rule.type, 'matchResourceOwner')
    assert.isUndefined(rule.property)
    assert.equal(rule.target, 'user-entity')
  }).tags(['@modeling', '@rule', '@match-resource-owner'])

  test('toJSON returns valid schema', ({ assert }) => {
    const rule = new MatchResourceOwnerAccessRule({ property: 'creatorId' })
    const json = rule.toJSON()

    assert.equal(json.type, 'matchResourceOwner')
    assert.equal(json.property, 'creatorId')
    assert.equal(json.target, 'property')
  }).tags(['@modeling', '@rule', '@match-resource-owner', '@serialization'])

  test('toJSON omits property when undefined', ({ assert }) => {
    const rule = new MatchResourceOwnerAccessRule({ target: 'user-entity' })
    const json = rule.toJSON()

    assert.equal(json.type, 'matchResourceOwner')
    assert.isUndefined(json.property)
    assert.equal(json.target, 'user-entity')
  }).tags(['@modeling', '@rule', '@match-resource-owner', '@serialization'])

  test('notifies change when property changes', async ({ assert }) => {
    const rule = new MatchResourceOwnerAccessRule()
    let notified = false
    rule.addEventListener('change', () => {
      notified = true
    })

    rule.property = 'ownerId'
    await Promise.resolve()
    assert.isTrue(notified)
  }).tags(['@modeling', '@rule', '@match-resource-owner', '@observed'])
})
