// Copyright 2024 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 sinon from 'sinon';
import * as i18n from '../../core/i18n/i18n.js';
import { raf, renderElementIntoDOM, } from '../../testing/DOMHelpers.js';
import { describeWithEnvironment, setupActionRegistry } from '../../testing/EnvironmentHelpers.js';
import { expectCalled } from '../../testing/ExpectStubCall.js';
import { createViewFunctionStub } from '../../testing/ViewFunctionHelpers.js';
import * as UI from '../../ui/legacy/legacy.js';
import * as Application from './application.js';
describeWithEnvironment('KeyValueStorageItemsView', () => {
    before(() => {
        UI.ActionRegistration.registerActionExtension({
            actionId: 'ai-assistance.storage-floating-button',
            category: "GLOBAL" /* UI.ActionRegistration.ActionCategory.GLOBAL */,
            title: i18n.i18n.lockedLazyString('Ask AI'),
        });
    });
    setupActionRegistry();
    let keyValueStorageItemsView;
    let viewFunction;
    const MOCK_ITEMS = [
        { key: 'foo', value: 'value1' },
        { key: 'bar', value: 'value2' },
    ];
    const createPreviewFunc = sinon.stub();
    const expectCreatePreviewCalled = async (expectedKey, expectedValue) => {
        createPreviewFunc.resetHistory();
        await expectCalled(createPreviewFunc, {
            fakeFn: async (key, value) => {
                assert.strictEqual(key, expectedKey);
                assert.strictEqual(value, expectedValue);
                return new UI.EmptyWidget.EmptyWidget(`${key}:${value}`, '');
            },
        });
    };
    class TestKeyValueStorageItemsView extends Application.KeyValueStorageItemsView.KeyValueStorageItemsView {
        setItem(_key, _value) {
            // Do nothing.
        }
        removeItem(_key) {
            // Do nothing.
        }
        createPreview(key, value) {
            return createPreviewFunc(key, value);
        }
        isAiButtonEnabled() {
            return UI.ActionRegistry.ActionRegistry.instance().hasAction('ai-assistance.storage-floating-button');
        }
        populateContextMenu(item, contextMenu) {
            super.populateContextMenu(item, contextMenu);
        }
        onAiButtonClick(item, event) {
            super.onAiButtonClick(item, event);
        }
    }
    beforeEach(() => {
        const container = new UI.Widget.VBox();
        const div = document.createElement('div');
        renderElementIntoDOM(div);
        container.markAsRoot();
        container.show(div);
        viewFunction = createViewFunctionStub(Application.KeyValueStorageItemsView.KeyValueStorageItemsView);
        keyValueStorageItemsView =
            new TestKeyValueStorageItemsView('Items', 'key-value-storage-items-view', true, viewFunction);
        keyValueStorageItemsView.showItems(MOCK_ITEMS);
    });
    afterEach(() => {
        keyValueStorageItemsView.detach();
    });
    it('updates preview when key selected', async () => {
        const { key, value } = MOCK_ITEMS[0];
        const createPreviewPromise = expectCreatePreviewCalled(key, value);
        // Select the first item by key.
        viewFunction.input.onSelect({ key, value });
        // Check createPreview function was called.
        await createPreviewPromise;
        assert.include(viewFunction.input.preview.element.innerText, `${key}:${value}`);
    });
    it('shows empty preview when no row is selected', async () => {
        viewFunction.input.onSelect(MOCK_ITEMS[0]);
        await raf();
        viewFunction.input.onSelect(null);
        // Check preview was updated.
        assert.include(viewFunction.input.preview.element.innerText, 'No value selectedSelect a value to preview');
    });
    it('preview changed when value changes', async () => {
        const { key, value } = MOCK_ITEMS[0];
        let createPreviewPromise = expectCreatePreviewCalled(key, value);
        // Select the first item.
        viewFunction.input.onSelect({ key, value });
        // Check createPreview function was called.
        await createPreviewPromise;
        // Update the item data (in reality, this would happen since a user edit
        // would trigger the refreshItems callback - which would fetch new data and
        // call showItems again).
        const updatedItems = structuredClone(MOCK_ITEMS);
        updatedItems[0].value = 'newValue';
        createPreviewPromise = expectCreatePreviewCalled(key, 'newValue');
        keyValueStorageItemsView.showItems(updatedItems);
        // Check createPreview function was called.
        await createPreviewPromise;
        // Check preview was updated.
        await raf();
        assert.include(viewFunction.input.preview.element.innerText, `${key}:newValue`);
    });
    it('clicking Ask AI button calls onAiButtonClick', () => {
        const onAiButtonClickSpy = sinon.spy(keyValueStorageItemsView, 'onAiButtonClick');
        keyValueStorageItemsView.performUpdate();
        const dummyEvent = new Event('click');
        viewFunction.input.onAiButtonClick?.(MOCK_ITEMS[0], dummyEvent);
        sinon.assert.calledOnceWithExactly(onAiButtonClickSpy, MOCK_ITEMS[0], dummyEvent);
    });
    it('right clicking calls populateContextMenu', () => {
        const populateContextMenuSpy = sinon.spy(keyValueStorageItemsView, 'populateContextMenu');
        keyValueStorageItemsView.performUpdate();
        const dummyEvent = new Event('contextmenu');
        const contextMenu = new UI.ContextMenu.ContextMenu(dummyEvent);
        viewFunction.input.onContextMenu?.(MOCK_ITEMS[0], contextMenu);
        sinon.assert.calledOnceWithExactly(populateContextMenuSpy, MOCK_ITEMS[0], contextMenu);
    });
});
//# sourceMappingURL=KeyValueStorageItemsView.test.js.map