@@ -98,7 +98,9 @@ vi.mock('../../src/lib/get-auth', () => ({
9898 getBrowserStackAuth : vi . fn ( ( ) => 'fake-user:fake-key' )
9999} ) ) ;
100100vi . mock ( '../../src/tools/testmanagement-utils/TCG-utils/api' , ( ) => ( {
101- projectIdentifierToId : vi . fn ( ( ) => Promise . resolve ( '999' ) )
101+ projectIdentifierToId : vi . fn ( ( ) => Promise . resolve ( '999' ) ) ,
102+ fetchFormFields : vi . fn ( ) ,
103+ normalizeDefaultFieldValue : vi . fn ( ) ,
102104} ) ) ;
103105vi . mock ( 'form-data' , ( ) => {
104106 return {
@@ -193,6 +195,9 @@ vi.mock('../../src/lib/apiClient', () => ({
193195vi . mock ( '../../src/lib/tm-base-url' , ( ) => ( {
194196 getTMBaseURL : vi . fn ( async ( ) => 'https://test-management.browserstack.com' ) ,
195197} ) ) ;
198+ vi . mock ( '../../src/logger' , ( ) => ( {
199+ default : { error : vi . fn ( ) , warn : vi . fn ( ) , info : vi . fn ( ) , debug : vi . fn ( ) } ,
200+ } ) ) ;
196201
197202
198203const mockedAxios = axios as Mocked < typeof axios > ;
@@ -1031,3 +1036,130 @@ describe('getSubTestPlan util — fail-soft enrichment', () => {
10311036 expect ( result . content ?. [ 0 ] ?. text ) . toContain ( 'Failed to fetch sub-test-plan' ) ;
10321037 } ) ;
10331038} ) ;
1039+
1040+ // Real function via importActual (the module is mocked at the top).
1041+ describe ( 'normalizeDefaultFieldValue' , ( ) => {
1042+ let normalize : typeof import ( '../../src/tools/testmanagement-utils/TCG-utils/api' ) . normalizeDefaultFieldValue ;
1043+
1044+ beforeAll ( async ( ) => {
1045+ const actual = await vi . importActual <
1046+ typeof import ( '../../src/tools/testmanagement-utils/TCG-utils/api' )
1047+ > ( '../../src/tools/testmanagement-utils/TCG-utils/api' ) ;
1048+ normalize = actual . normalizeDefaultFieldValue ;
1049+ } ) ;
1050+
1051+ const values = [
1052+ { name : 'Critical' , internal_name : 'critical' , value : 1 } ,
1053+ { name : 'Medium' , internal_name : 'medium' , value : 2 } ,
1054+ ] ;
1055+
1056+ it ( 'resolves a lowercase internal name to the Title-Case display name' , ( ) => {
1057+ expect ( normalize ( values , 'critical' , 'name' ) ) . toBe ( 'Critical' ) ;
1058+ } ) ;
1059+
1060+ it ( 'matches case-insensitively regardless of input casing' , ( ) => {
1061+ expect ( normalize ( values , 'CRITICAL' , 'name' ) ) . toBe ( 'Critical' ) ;
1062+ expect ( normalize ( values , ' Critical ' , 'name' ) ) . toBe ( 'Critical' ) ;
1063+ } ) ;
1064+
1065+ it ( 'resolves a display name to the internal name when emit is internal_name' , ( ) => {
1066+ expect ( normalize ( values , 'Critical' , 'internal_name' ) ) . toBe ( 'critical' ) ;
1067+ } ) ;
1068+
1069+ it ( 'returns undefined when no option matches (caller passes raw value through)' , ( ) => {
1070+ expect ( normalize ( values , 'urgent' , 'name' ) ) . toBeUndefined ( ) ;
1071+ expect ( normalize ( [ ] , 'critical' , 'name' ) ) . toBeUndefined ( ) ;
1072+ } ) ;
1073+ } ) ;
1074+
1075+ // Real createTestCase via importActual; collaborators are mocked at module scope.
1076+ describe ( 'createTestCase — priority normalization' , ( ) => {
1077+ let createTestCaseReal : typeof import ( '../../src/tools/testmanagement-utils/create-testcase' ) . createTestCase ;
1078+ let apiClientMock : typeof import ( '../../src/lib/apiClient' ) . apiClient ;
1079+ let fetchFormFieldsMock : Mock ;
1080+ let normalizeMock : Mock ;
1081+
1082+ beforeAll ( async ( ) => {
1083+ const actual = await vi . importActual <
1084+ typeof import ( '../../src/tools/testmanagement-utils/create-testcase' )
1085+ > ( '../../src/tools/testmanagement-utils/create-testcase' ) ;
1086+ createTestCaseReal = actual . createTestCase ;
1087+ apiClientMock = ( await import ( '../../src/lib/apiClient' ) ) . apiClient ;
1088+ const api = await import ( '../../src/tools/testmanagement-utils/TCG-utils/api' ) ;
1089+ fetchFormFieldsMock = api . fetchFormFields as unknown as Mock ;
1090+ normalizeMock = api . normalizeDefaultFieldValue as unknown as Mock ;
1091+ } ) ;
1092+
1093+ beforeEach ( ( ) => {
1094+ vi . clearAllMocks ( ) ;
1095+ } ) ;
1096+
1097+ // Priority options as returned by fetchFormFields.
1098+ const priorityValues = [
1099+ { name : 'Critical' , internal_name : 'critical' , value : 1 } ,
1100+ { name : 'Medium' , internal_name : 'medium' , value : 2 } ,
1101+ ] ;
1102+ const formFields = {
1103+ default_fields : { priority : { values : priorityValues } } ,
1104+ custom_fields : { } ,
1105+ } ;
1106+ const createSuccess = {
1107+ data : {
1108+ data : {
1109+ success : true ,
1110+ test_case : {
1111+ identifier : 'TC-1' ,
1112+ title : 'Sample' ,
1113+ priority : 'Critical' ,
1114+ folder_id : 1 ,
1115+ } ,
1116+ } ,
1117+ } ,
1118+ } ;
1119+
1120+ const baseArgs = {
1121+ project_identifier : 'PR-1' ,
1122+ folder_id : 'F-1' ,
1123+ name : 'Sample' ,
1124+ test_case_steps : [ { step : 'a' , result : 'b' } ] ,
1125+ } ;
1126+
1127+ it ( 'looks up the project form fields and sends the normalized priority in the request body' , async ( ) => {
1128+ fetchFormFieldsMock . mockResolvedValue ( formFields ) ;
1129+ normalizeMock . mockReturnValue ( 'Critical' ) ;
1130+ ( apiClientMock . post as Mock ) . mockResolvedValueOnce ( createSuccess ) ;
1131+
1132+ const result = await createTestCaseReal (
1133+ { ...baseArgs , priority : 'critical' } ,
1134+ mockConfig as any ,
1135+ ) ;
1136+
1137+ expect ( result . isError ) . toBeFalsy ( ) ;
1138+ expect ( normalizeMock ) . toHaveBeenCalledWith ( priorityValues , 'critical' , 'name' ) ;
1139+ const body = ( apiClientMock . post as Mock ) . mock . calls [ 0 ] [ 0 ] . body ;
1140+ expect ( body . test_case . priority ) . toBe ( 'Critical' ) ;
1141+ } ) ;
1142+
1143+ it ( 'omits priority from the request body when not provided (preserves project default)' , async ( ) => {
1144+ ( apiClientMock . post as Mock ) . mockResolvedValueOnce ( createSuccess ) ;
1145+
1146+ await createTestCaseReal ( { ...baseArgs } , mockConfig as any ) ;
1147+
1148+ expect ( fetchFormFieldsMock ) . not . toHaveBeenCalled ( ) ;
1149+ const body = ( apiClientMock . post as Mock ) . mock . calls [ 0 ] [ 0 ] . body ;
1150+ expect ( body . test_case ) . not . toHaveProperty ( 'priority' ) ;
1151+ } ) ;
1152+
1153+ it ( 'passes the raw priority through when the form-fields lookup fails (graceful fallback)' , async ( ) => {
1154+ fetchFormFieldsMock . mockRejectedValue ( new Error ( 'Network Error' ) ) ;
1155+ ( apiClientMock . post as Mock ) . mockResolvedValueOnce ( createSuccess ) ;
1156+
1157+ await createTestCaseReal (
1158+ { ...baseArgs , priority : 'critical' } ,
1159+ mockConfig as any ,
1160+ ) ;
1161+
1162+ const body = ( apiClientMock . post as Mock ) . mock . calls [ 0 ] [ 0 ] . body ;
1163+ expect ( body . test_case . priority ) . toBe ( 'critical' ) ;
1164+ } ) ;
1165+ } ) ;
0 commit comments