// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { assert } from 'chai';
import * as Common from '../../../core/common/common.js';
import * as Platform from '../../../core/platform/platform.js';
import * as SDK from '../../../core/sdk/sdk.js';
import * as TextUtils from '../../text_utils/text_utils.js';
import { NetworkRequestFormatter } from '../ai_assistance.js';
const { urlString } = Platform.DevToolsPath;
describe('NetworkRequestFormatter', () => {
    describe('allowHeader', () => {
        it('allows a header from the list', () => {
            assert.isTrue(NetworkRequestFormatter.NetworkRequestFormatter.allowHeader('content-type'));
        });
        it('disallows headers not on the list', () => {
            assert.isFalse(NetworkRequestFormatter.NetworkRequestFormatter.allowHeader('cookie'));
            assert.isFalse(NetworkRequestFormatter.NetworkRequestFormatter.allowHeader('set-cookie'));
            assert.isFalse(NetworkRequestFormatter.NetworkRequestFormatter.allowHeader('authorization'));
        });
    });
    describe('formatInitiatorUrl', () => {
        const tests = [
            {
                allowedResource: 'https://example.test',
                targetResource: 'https://example.test',
                shouldBeRedacted: false,
            },
            {
                allowedResource: 'https://example.test',
                targetResource: 'https://another-example.test',
                shouldBeRedacted: true,
            },
            {
                allowedResource: 'file://test',
                targetResource: 'https://another-example.test',
                shouldBeRedacted: true,
            },
            {
                allowedResource: 'https://another-example.test',
                targetResource: 'file://test',
                shouldBeRedacted: true,
            },
            {
                allowedResource: 'https://test.example.test',
                targetResource: 'https://example.test',
                shouldBeRedacted: true,
            },
            {
                allowedResource: 'https://test.example.test:9900',
                targetResource: 'https://test.example.test:9901',
                shouldBeRedacted: true,
            },
            {
                allowedResource: 'invalid-url',
                targetResource: 'invalid-url',
                shouldBeRedacted: true,
            },
            {
                allowedResource: 'https://example.test',
                targetResource: 'invalid-url',
                shouldBeRedacted: true,
            },
            {
                allowedResource: 'invalid-url',
                targetResource: 'https://example.test',
                shouldBeRedacted: true,
            },
        ];
        for (const t of tests) {
            it(`${t.targetResource} test when allowed resource is ${t.allowedResource}`, () => {
                const allowedOrigin = Common.ParsedURL.ParsedURL.extractOrigin(urlString `${t.allowedResource}`);
                const formatted = NetworkRequestFormatter.NetworkRequestFormatter.formatInitiatorUrl(urlString `${t.targetResource}`, allowedOrigin);
                if (t.shouldBeRedacted) {
                    assert.strictEqual(formatted, '<redacted cross-origin initiator URL>', `${JSON.stringify(t)} was not redacted`);
                }
                else {
                    assert.strictEqual(formatted, t.targetResource, `${JSON.stringify(t)} was redacted`);
                }
            });
        }
    });
    describe('formatBody', () => {
        const fakeRequest = SDK.NetworkRequest.NetworkRequest.createWithoutBackendRequest('fakeRequestId', Platform.DevToolsPath.urlString `url1`, Platform.DevToolsPath.urlString `documentURL`, null);
        it('handles empty response correctly', async () => {
            fakeRequest.requestContentData = () => {
                return Promise.resolve(new TextUtils.ContentData.ContentData('', false, ''));
            };
            const result = await NetworkRequestFormatter.NetworkRequestFormatter.formatBody('test:', fakeRequest, 100);
            assert.strictEqual(result, 'test:\n<empty response>');
        });
        it('handles base64 text correctly', async () => {
            fakeRequest.requestContentData = () => {
                return Promise.resolve(new TextUtils.ContentData.ContentData('some base64 string', true, ''));
            };
            const result = await NetworkRequestFormatter.NetworkRequestFormatter.formatBody('test:', fakeRequest, 100);
            assert.strictEqual(result, 'test:\n<binary data>');
        });
        it('handles the text limit correctly', async () => {
            fakeRequest.requestContentData = () => {
                return Promise.resolve(new TextUtils.ContentData.ContentData('some text that is longer than expected', false, 'text/plain'));
            };
            const result = await NetworkRequestFormatter.NetworkRequestFormatter.formatBody('test:', fakeRequest, 20);
            assert.strictEqual(result, `test:\nsome text that is lo... <truncated>`);
        });
        it('handles the text format correctly', async () => {
            fakeRequest.requestContentData = () => {
                return Promise.resolve(new TextUtils.ContentData.ContentData(JSON.stringify({ response: 'body' }), false, 'application/json'));
            };
            const result = await NetworkRequestFormatter.NetworkRequestFormatter.formatBody('test:', fakeRequest, 100);
            assert.strictEqual(result, `test:\n${JSON.stringify({ response: 'body' })}`);
        });
        it('handles error correctly', async () => {
            fakeRequest.requestContentData = () => {
                return Promise.resolve({
                    error: 'an error has occurred',
                });
            };
            const result = await NetworkRequestFormatter.NetworkRequestFormatter.formatBody('test:', fakeRequest, 100);
            assert.strictEqual(result, '');
        });
    });
    describe('formatHeaders', () => {
        it('does not redact a header from the list', () => {
            assert.strictEqual(NetworkRequestFormatter.NetworkRequestFormatter.formatHeaders('test:', [{ name: 'content-type', value: 'foo' }]), 'test:\ncontent-type: foo');
        });
        it('disallows headers not on the list', () => {
            assert.strictEqual(NetworkRequestFormatter.NetworkRequestFormatter.formatHeaders('test:', [{ name: 'cookie', value: 'foo' }]), 'test:\ncookie: <redacted>');
            assert.strictEqual(NetworkRequestFormatter.NetworkRequestFormatter.formatHeaders('test:', [{ name: 'set-cookie', value: 'foo' }]), 'test:\nset-cookie: <redacted>');
            assert.strictEqual(NetworkRequestFormatter.NetworkRequestFormatter.formatHeaders('test:', [{ name: 'authorization', value: 'foo' }]), 'test:\nauthorization: <redacted>');
        });
    });
    describe('formatStatus', () => {
        it('handles pending state correctly', () => {
            assert.strictEqual(NetworkRequestFormatter.NetworkRequestFormatter.formatStatus({
                statusCode: 0,
                statusText: '',
                failed: false,
                canceled: false,
                preserved: false,
                finished: false,
            }), 'Network request status: pending\n');
        });
        it('handles finished state with status code correctly', () => {
            assert.strictEqual(NetworkRequestFormatter.NetworkRequestFormatter.formatStatus({
                statusCode: 200,
                statusText: 'OK',
                failed: false,
                canceled: false,
                preserved: false,
                finished: true,
            }), 'Response status: 200 OK\nNetwork request status: finished\n');
        });
        it('handles finished state with status code and empty status text correctly', () => {
            assert.strictEqual(NetworkRequestFormatter.NetworkRequestFormatter.formatStatus({
                statusCode: 200,
                statusText: '',
                failed: false,
                canceled: false,
                preserved: false,
                finished: true,
            }), 'Response status: 200\nNetwork request status: finished\n');
        });
        it('handles preserved state correctly', () => {
            assert.strictEqual(NetworkRequestFormatter.NetworkRequestFormatter.formatStatus({
                statusCode: 0,
                statusText: '',
                failed: false,
                canceled: false,
                preserved: true,
                finished: true,
            }), 'Network request status: finished, preserved\n');
        });
        it('handles failed and canceled states correctly', () => {
            assert.strictEqual(NetworkRequestFormatter.NetworkRequestFormatter.formatStatus({
                statusCode: 0,
                statusText: '',
                failed: true,
                canceled: true,
                preserved: false,
                finished: true,
            }), 'Network request status: finished, failed, canceled\n');
        });
    });
    describe('formatFailureReasons', () => {
        it('handles no failure reason correctly', () => {
            assert.strictEqual(NetworkRequestFormatter.NetworkRequestFormatter.formatFailureReasons({
                blockedReason: undefined,
                corsErrorStatus: undefined,
                localizedFailDescription: null,
            }), '');
        });
        it('handles blocked reason correctly', () => {
            assert.strictEqual(NetworkRequestFormatter.NetworkRequestFormatter.formatFailureReasons({
                blockedReason: "inspector" /* Protocol.Network.BlockedReason.Inspector */,
                corsErrorStatus: undefined,
                localizedFailDescription: null,
            }), 'Blocked reason: a custom network condition in DevTools is blocking this request\n');
        });
        it('handles CORS error correctly', () => {
            assert.strictEqual(NetworkRequestFormatter.NetworkRequestFormatter.formatFailureReasons({
                blockedReason: undefined,
                corsErrorStatus: {
                    corsError: "AllowOriginMismatch" /* Protocol.Network.CorsError.AllowOriginMismatch */,
                    failedParameter: 'foo',
                },
                localizedFailDescription: null,
            }), 'CORS error: AllowOriginMismatch foo\n');
        });
        it('handles localized fail description correctly', () => {
            assert.strictEqual(NetworkRequestFormatter.NetworkRequestFormatter.formatFailureReasons({
                blockedReason: undefined,
                corsErrorStatus: undefined,
                localizedFailDescription: 'net::ERR_FAILED',
            }), 'Fail description: net::ERR_FAILED\n');
        });
    });
});
//# sourceMappingURL=NetworkRequestFormatter.test.js.map