basant307/AI_Governance_Project
045
1/**2 * @license3 * Copyright 2026 Qwen Team4 * SPDX-License-Identifier: Apache-2.05 */6 7import { describe, expect, it } from 'vitest';8import {9 appendUserPromptExpansionAdditionalContext,10 formatUserPromptExpansionBlockedMessage,11 serializeUserPromptExpansionPrompt,12} from './userPromptExpansionHook.js';13 14describe('appendUserPromptExpansionAdditionalContext', () => {15 it('returns content unchanged when additionalContext is undefined', () => {16 expect(17 appendUserPromptExpansionAdditionalContext('base prompt', undefined),18 ).toBe('base prompt');19 });20 21 it('appends additional context to string prompts', () => {22 const result = appendUserPromptExpansionAdditionalContext(23 'base prompt',24 'hook context',25 );26 27 expect(result).toBe('base prompt\n\nhook context');28 });29 30 it('appends additional context to part arrays', () => {31 const result = appendUserPromptExpansionAdditionalContext(32 [{ text: 'base prompt' }],33 'hook context',34 );35 36 expect(result).toEqual([37 { text: 'base prompt' },38 { text: '\n\nhook context' },39 ]);40 });41 42 it('appends additional context to a single part', () => {43 const result = appendUserPromptExpansionAdditionalContext(44 { text: 'base prompt' },45 'hook context',46 );47 48 expect(result).toEqual([49 { text: 'base prompt' },50 { text: '\n\nhook context' },51 ]);52 });53});54 55describe('formatUserPromptExpansionBlockedMessage', () => {56 it('escapes ampersands before angle brackets', () => {57 const result = formatUserPromptExpansionBlockedMessage('a&b<c>');58 59 expect(result).toBe('UserPromptExpansion blocked: a&b<c>');60 });61 62 it('sanitizes and truncates block reasons', () => {63 const longReason = `<policy>${'x'.repeat(10_000)}</policy>`;64 65 const result = formatUserPromptExpansionBlockedMessage(longReason);66 67 expect(result).toBe(68 `UserPromptExpansion blocked: <policy>${'x'.repeat(9_986)}`,69 );70 expect(result.length).toBe('UserPromptExpansion blocked: '.length + 10_000);71 });72 73 it('does not leave a partial entity after truncation', () => {74 const result = formatUserPromptExpansionBlockedMessage(75 'x'.repeat(9_999) + '<',76 );77 78 expect(result).toBe(`UserPromptExpansion blocked: ${'x'.repeat(9_999)}`);79 });80 81 it('does not leave a partial ampersand entity after truncation', () => {82 const result = formatUserPromptExpansionBlockedMessage(83 'x'.repeat(9_998) + '&',84 );85 86 expect(result).toBe(`UserPromptExpansion blocked: ${'x'.repeat(9_998)}`);87 });88});89 90describe('serializeUserPromptExpansionPrompt', () => {91 it('returns string prompts unchanged', () => {92 expect(serializeUserPromptExpansionPrompt('plain prompt')).toBe(93 'plain prompt',94 );95 });96 97 it('serializes part arrays with verbose formatting', () => {98 expect(99 serializeUserPromptExpansionPrompt([100 { text: 'first' },101 { inlineData: { mimeType: 'text/plain', data: 'ZGF0YQ==' } },102 { text: 'last' },103 ]),104 ).toBe('first<text/plain>last');105 });106 107 it('serializes a single part object', () => {108 expect(serializeUserPromptExpansionPrompt({ text: 'single part' })).toBe(109 'single part',110 );111 });112 113 it('serializes empty part arrays to an empty string', () => {114 expect(serializeUserPromptExpansionPrompt([])).toBe('');115 });116});117 