import { describe, expect, it } from 'bun:test';
import { DwnErrorCode } from '../../src/core/dwn-error.js';
import { GrantAuthorization } from '../../src/core/grant-authorization.js';
describe('GrantAuthorization', () => {
    describe('verifyGrantScopeInterfaceAndMethod', () => {
        const validationStateReader = {
            fetchOldestGrantRevocation: async () => undefined,
        };
        it('should reject Messages grant with method !== Read', async () => {
            // Build a minimal mock that passes grantor/grantee/active checks
            // but has a malformed Messages scope.
            const mockGrant = {
                id: 'grant-malformed',
                grantor: 'did:example:grantor',
                grantee: 'did:example:grantee',
                dateGranted: '2020-01-01T00:00:00.000Z',
                dateExpires: '2040-01-01T00:00:00.000Z',
                scope: { interface: 'Messages', method: 'Sync', protocol: 'https://proto.example' },
            };
            const mockMessage = {
                descriptor: {
                    interface: 'Messages',
                    method: 'Sync',
                    messageTimestamp: '2025-01-01T00:00:00.000Z',
                },
            };
            await expect(GrantAuthorization.performBaseValidation({
                incomingMessage: mockMessage,
                expectedGrantor: 'did:example:grantor',
                expectedGrantee: 'did:example:grantee',
                permissionGrant: mockGrant,
                validationStateReader: validationStateReader,
            })).rejects.toThrow(DwnErrorCode.GrantAuthorizationMethodMismatch);
        });
        it('allows Records Read grants to authorize read-like record methods', async () => {
            const mockGrant = {
                id: 'grant-records-read',
                grantor: 'did:example:grantor',
                grantee: 'did:example:grantee',
                dateGranted: '2020-01-01T00:00:00.000Z',
                dateExpires: '2040-01-01T00:00:00.000Z',
                scope: { interface: 'Records', method: 'Read', protocol: 'https://proto.example' },
            };
            for (const method of ['Read', 'Query', 'Subscribe', 'Count']) {
                const mockMessage = {
                    descriptor: {
                        interface: 'Records',
                        method,
                        messageTimestamp: '2025-01-01T00:00:00.000Z',
                    },
                };
                await expect(GrantAuthorization.performBaseValidation({
                    incomingMessage: mockMessage,
                    expectedGrantor: 'did:example:grantor',
                    expectedGrantee: 'did:example:grantee',
                    permissionGrant: mockGrant,
                    validationStateReader: validationStateReader,
                })).resolves.toBeUndefined();
            }
        });
        it('rejects Records Write grants for read-like record methods', async () => {
            const mockGrant = {
                id: 'grant-records-write',
                grantor: 'did:example:grantor',
                grantee: 'did:example:grantee',
                dateGranted: '2020-01-01T00:00:00.000Z',
                dateExpires: '2040-01-01T00:00:00.000Z',
                scope: { interface: 'Records', method: 'Write', protocol: 'https://proto.example' },
            };
            for (const method of ['Read', 'Query', 'Subscribe', 'Count']) {
                const mockMessage = {
                    descriptor: {
                        interface: 'Records',
                        method,
                        messageTimestamp: '2025-01-01T00:00:00.000Z',
                    },
                };
                await expect(GrantAuthorization.performBaseValidation({
                    incomingMessage: mockMessage,
                    expectedGrantor: 'did:example:grantor',
                    expectedGrantee: 'did:example:grantee',
                    permissionGrant: mockGrant,
                    validationStateReader: validationStateReader,
                })).rejects.toThrow(DwnErrorCode.GrantAuthorizationMethodMismatch);
            }
        });
        it('rejects grants scoped to a different DWN interface', async () => {
            const mockGrant = {
                id: 'grant-records-read',
                grantor: 'did:example:grantor',
                grantee: 'did:example:grantee',
                dateGranted: '2020-01-01T00:00:00.000Z',
                dateExpires: '2040-01-01T00:00:00.000Z',
                scope: { interface: 'Records', method: 'Read', protocol: 'https://proto.example' },
            };
            const mockMessage = {
                descriptor: {
                    interface: 'Messages',
                    method: 'Read',
                    messageTimestamp: '2025-01-01T00:00:00.000Z',
                },
            };
            await expect(GrantAuthorization.performBaseValidation({
                incomingMessage: mockMessage,
                expectedGrantor: 'did:example:grantor',
                expectedGrantee: 'did:example:grantee',
                permissionGrant: mockGrant,
                validationStateReader: validationStateReader,
            })).rejects.toThrow(DwnErrorCode.GrantAuthorizationInterfaceMismatch);
        });
        it('rejects read-like Records grants that do not use method Read', async () => {
            for (const method of ['Query', 'Subscribe', 'Count']) {
                const mockGrant = {
                    id: `grant-records-${method.toLowerCase()}`,
                    grantor: 'did:example:grantor',
                    grantee: 'did:example:grantee',
                    dateGranted: '2020-01-01T00:00:00.000Z',
                    dateExpires: '2040-01-01T00:00:00.000Z',
                    scope: { interface: 'Records', method, protocol: 'https://proto.example' },
                };
                const mockMessage = {
                    descriptor: {
                        interface: 'Records',
                        method,
                        messageTimestamp: '2025-01-01T00:00:00.000Z',
                    },
                };
                await expect(GrantAuthorization.performBaseValidation({
                    incomingMessage: mockMessage,
                    expectedGrantor: 'did:example:grantor',
                    expectedGrantee: 'did:example:grantee',
                    permissionGrant: mockGrant,
                    validationStateReader: validationStateReader,
                })).rejects.toThrow(DwnErrorCode.GrantAuthorizationMethodMismatch);
            }
        });
    });
});
//# sourceMappingURL=grant-authorization.spec.js.map