| // Copyright 2026 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 {afterEach, before, beforeEach, describe, it} from 'mocha'; | |
| import sinon from 'sinon'; | |
| import * as Common from '../../core/common/common.js'; | |
| import * as i18n from '../../core/i18n/i18n.js'; | |
| import * as Platform from '../../core/platform/platform.js'; | |
| import * as SDK from '../../core/sdk/sdk.js'; | |
| import * as AiAssistance from '../../models/ai_assistance/ai_assistance.js'; | |
| import {setupLocaleHooks} from '../../testing/LocaleHelpers.js'; | |
| import {TestUniverse} from '../../testing/TestUniverse.js'; | |
| import {createViewFunctionStub, type ViewFunctionStub} from '../../testing/ViewFunctionHelpers.js'; | |
| import * as UI from '../../ui/legacy/legacy.js'; | |
| import * as Application from './application.js'; | |
| const {urlString} = Platform.DevToolsPath; | |
| describe('CookieItemsView', () => { | |
| setupLocaleHooks(); | |
| before(() => { | |
| UI.ActionRegistration.maybeRemoveActionExtension('ai-assistance.storage-floating-button'); | |
| UI.ActionRegistration.maybeRemoveActionExtension('ai-assistance.application-panel-context'); | |
| UI.ActionRegistration.registerActionExtension({ | |
| actionId: 'ai-assistance.storage-floating-button', | |
| category: UI.ActionRegistration.ActionCategory.GLOBAL, | |
| title: i18n.i18n.lockedLazyString('Ask AI'), | |
| }); | |
| UI.ActionRegistration.registerActionExtension({ | |
| actionId: 'ai-assistance.application-panel-context', | |
| category: UI.ActionRegistration.ActionCategory.GLOBAL, | |
| title: i18n.i18n.lockedLazyString('Debug with AI'), | |
| contextTypes() { | |
| return [AiAssistance.StorageItem.StorageItem]; | |
| }, | |
| }); | |
| }); | |
| afterEach(() => { | |
| UI.ShortcutRegistry.ShortcutRegistry.removeInstance(); | |
| UI.ActionRegistry.ActionRegistry.removeInstance(); | |
| }); | |
| let universe: TestUniverse; | |
| let cookieItemsView: Application.CookieItemsView.CookieItemsView; | |
| let viewFunction: ViewFunctionStub<typeof Application.CookieItemsView.CookieItemsView>; | |
| let mockCookieModel: sinon.SinonStubbedInstance<SDK.CookieModel.CookieModel>; | |
| beforeEach(() => { | |
| universe = new TestUniverse(); | |
| sinon.stub(Common.Settings.Settings, 'instance').returns(universe.settings); | |
| sinon.stub(SDK.TargetManager.TargetManager, 'instance').returns(universe.targetManager); | |
| const actionRegistry = UI.ActionRegistry.ActionRegistry.instance({forceNew: true}); | |
| UI.ShortcutRegistry.ShortcutRegistry.instance({ | |
| forceNew: true, | |
| actionRegistry, | |
| }); | |
| universe.createTarget({url: urlString`http://example.com`}).setInspectedURL(urlString`http://example.com`); | |
| mockCookieModel = sinon.createStubInstance(SDK.CookieModel.CookieModel); | |
| mockCookieModel.getCookiesForDomain.resolves([]); | |
| viewFunction = createViewFunctionStub(Application.CookieItemsView.CookieItemsView); | |
| cookieItemsView = new Application.CookieItemsView.CookieItemsView( | |
| mockCookieModel as unknown as SDK.CookieModel.CookieModel, 'example.com', viewFunction); | |
| }); | |
| it('clicking Ask AI button triggers the action', () => { | |
| const actionRegistry = UI.ActionRegistry.ActionRegistry.instance(); | |
| const action = actionRegistry.getAction('ai-assistance.storage-floating-button'); | |
| const executeStub = sinon.stub(action, 'execute'); | |
| cookieItemsView.performUpdate(); | |
| const dummyEvent = new Event('click'); | |
| const cookie = new SDK.Cookie.Cookie('cookie-name', 'value'); | |
| viewFunction.input.onAiButtonClick?.(cookie, dummyEvent); | |
| sinon.assert.calledOnce(executeStub); | |
| }); | |
| it('populates context menu with Debug with AI submenu and expected items', () => { | |
| cookieItemsView.performUpdate(); | |
| // Stub UI.Context flavor | |
| const contextFlavorStub = sinon.stub(UI.Context.Context.instance(), 'flavor'); | |
| const dummyStorageItem = {} as AiAssistance.StorageItem.StorageItem; | |
| contextFlavorStub.withArgs(AiAssistance.StorageItem.StorageItem).returns(dummyStorageItem); | |
| const dummyEvent = new Event('contextmenu'); | |
| const contextMenu = new UI.ContextMenu.ContextMenu(dummyEvent); | |
| const cookie = new SDK.Cookie.Cookie('cookie-name', 'value'); | |
| viewFunction.input.onPopulateAiContextMenu?.(cookie, contextMenu); | |
| const debugWithAiItem = contextMenu.buildDescriptor().subItems?.find(item => item.label === 'Debug with AI'); | |
| assert.exists(debugWithAiItem, 'Expected Debug with AI context menu item'); | |
| assert.deepEqual(debugWithAiItem?.subItems?.map(item => item.label), ['Start a chat', 'Explain this cookie']); | |
| }); | |
| it('sets StorageItem flavor on select', () => { | |
| cookieItemsView.performUpdate(); | |
| const cookie = new SDK.Cookie.Cookie('cookie-name', 'value'); | |
| cookie.addAttribute(SDK.Cookie.Attribute.DOMAIN, 'example.com'); | |
| viewFunction.input.onSelect(cookie); | |
| const flavor = UI.Context.Context.instance().flavor(AiAssistance.StorageItem.StorageItem); | |
| assert.exists(flavor); | |
| assert.instanceOf(flavor, AiAssistance.StorageItem.CookieItem); | |
| assert.strictEqual((flavor as AiAssistance.StorageItem.CookieItem).name, 'cookie-name'); | |
| assert.strictEqual((flavor as AiAssistance.StorageItem.CookieItem).origin, 'example.com'); | |
| }); | |
| }); |