@@ -28,10 +28,11 @@ const createMockCustomService = (): CustomService =>
2828 } ) as unknown as CustomService ;
2929
3030// Create a mock ConfigService
31- const createMockConfigService = ( ) : ConfigService =>
31+ const createMockConfigService = ( language ?: string ) : ConfigService =>
3232 ( {
3333 getProjectRoot : vi . fn ( ) . mockReturnValue ( '/test/project' ) ,
3434 getSettings : vi . fn ( ) . mockResolvedValue ( { } ) ,
35+ getLanguage : vi . fn ( ) . mockResolvedValue ( language ) ,
3536 } ) as unknown as ConfigService ;
3637
3738describe ( 'RulesService' , ( ) => {
@@ -307,6 +308,141 @@ describe('RulesService', () => {
307308 'Failed to read rule file' ,
308309 ) ;
309310 } ) ;
311+
312+ describe ( 'language override from config' , ( ) => {
313+ it ( 'should override communication.language with config language' , async ( ) => {
314+ const mockAgent = {
315+ name : 'Frontend Developer' ,
316+ description : 'Frontend development specialist' ,
317+ role : {
318+ title : 'Senior Frontend Developer' ,
319+ expertise : [ 'React' , 'TypeScript' ] ,
320+ } ,
321+ communication : {
322+ language : 'en' ,
323+ style : 'Technical and precise' ,
324+ } ,
325+ } ;
326+ vi . mocked ( fs . readFile ) . mockResolvedValue ( JSON . stringify ( mockAgent ) ) ;
327+
328+ // Create service with config language 'ko'
329+ const serviceWithLang = new RulesService (
330+ createMockCustomService ( ) ,
331+ createMockConfigService ( 'ko' ) ,
332+ ) ;
333+
334+ const result = await serviceWithLang . getAgent ( 'frontend-developer' ) ;
335+
336+ expect ( result . communication ?. language ) . toBe ( 'ko' ) ;
337+ // Other communication properties should be preserved
338+ expect ( result . communication ?. style ) . toBe ( 'Technical and precise' ) ;
339+ } ) ;
340+
341+ it ( 'should preserve agent language when config has no language' , async ( ) => {
342+ const mockAgent = {
343+ name : 'Frontend Developer' ,
344+ description : 'Frontend development specialist' ,
345+ role : {
346+ title : 'Senior Frontend Developer' ,
347+ expertise : [ 'React' , 'TypeScript' ] ,
348+ } ,
349+ communication : {
350+ language : 'en' ,
351+ } ,
352+ } ;
353+ vi . mocked ( fs . readFile ) . mockResolvedValue ( JSON . stringify ( mockAgent ) ) ;
354+
355+ // Create service with no config language
356+ const serviceWithoutLang = new RulesService (
357+ createMockCustomService ( ) ,
358+ createMockConfigService ( undefined ) ,
359+ ) ;
360+
361+ const result = await serviceWithoutLang . getAgent ( 'frontend-developer' ) ;
362+
363+ expect ( result . communication ?. language ) . toBe ( 'en' ) ;
364+ } ) ;
365+
366+ it ( 'should create communication object with config language when agent has none' , async ( ) => {
367+ const mockAgent = {
368+ name : 'Frontend Developer' ,
369+ description : 'Frontend development specialist' ,
370+ role : {
371+ title : 'Senior Frontend Developer' ,
372+ expertise : [ 'React' , 'TypeScript' ] ,
373+ } ,
374+ // No communication field
375+ } ;
376+ vi . mocked ( fs . readFile ) . mockResolvedValue ( JSON . stringify ( mockAgent ) ) ;
377+
378+ // Create service with config language 'ja'
379+ const serviceWithLang = new RulesService (
380+ createMockCustomService ( ) ,
381+ createMockConfigService ( 'ja' ) ,
382+ ) ;
383+
384+ const result = await serviceWithLang . getAgent ( 'frontend-developer' ) ;
385+
386+ expect ( result . communication ?. language ) . toBe ( 'ja' ) ;
387+ } ) ;
388+
389+ it ( 'should not modify agent when config language is undefined and agent has no communication' , async ( ) => {
390+ const mockAgent = {
391+ name : 'Frontend Developer' ,
392+ description : 'Frontend development specialist' ,
393+ role : {
394+ title : 'Senior Frontend Developer' ,
395+ expertise : [ 'React' , 'TypeScript' ] ,
396+ } ,
397+ // No communication field
398+ } ;
399+ vi . mocked ( fs . readFile ) . mockResolvedValue ( JSON . stringify ( mockAgent ) ) ;
400+
401+ // Create service without config language
402+ const serviceWithoutLang = new RulesService (
403+ createMockCustomService ( ) ,
404+ createMockConfigService ( undefined ) ,
405+ ) ;
406+
407+ const result = await serviceWithoutLang . getAgent ( 'frontend-developer' ) ;
408+
409+ expect ( result . communication ) . toBeUndefined ( ) ;
410+ } ) ;
411+
412+ it ( 'should return agent with original language when getLanguage() fails' , async ( ) => {
413+ const mockAgent = {
414+ name : 'Frontend Developer' ,
415+ description : 'Frontend development specialist' ,
416+ role : {
417+ title : 'Senior Frontend Developer' ,
418+ expertise : [ 'React' , 'TypeScript' ] ,
419+ } ,
420+ communication : {
421+ language : 'en' ,
422+ style : 'Technical and precise' ,
423+ } ,
424+ } ;
425+ vi . mocked ( fs . readFile ) . mockResolvedValue ( JSON . stringify ( mockAgent ) ) ;
426+
427+ // Create service with failing getLanguage
428+ const failingConfigService = {
429+ getProjectRoot : vi . fn ( ) . mockReturnValue ( '/test/project' ) ,
430+ getSettings : vi . fn ( ) . mockResolvedValue ( { } ) ,
431+ getLanguage : vi . fn ( ) . mockRejectedValue ( new Error ( 'Config error' ) ) ,
432+ } as unknown as ConfigService ;
433+
434+ const serviceWithError = new RulesService (
435+ createMockCustomService ( ) ,
436+ failingConfigService ,
437+ ) ;
438+
439+ const result = await serviceWithError . getAgent ( 'frontend-developer' ) ;
440+
441+ // Should still return agent with original language
442+ expect ( result . communication ?. language ) . toBe ( 'en' ) ;
443+ expect ( result . communication ?. style ) . toBe ( 'Technical and precise' ) ;
444+ } ) ;
445+ } ) ;
310446 } ) ;
311447
312448 describe ( 'searchRules' , ( ) => {
0 commit comments