@@ -97,11 +97,17 @@ vi.mock('../../src/lib/inmemory-store', () => ({ signedUrlMap: new Map() }));
9797vi . mock ( '../../src/lib/get-auth' , ( ) => ( {
9898 getBrowserStackAuth : vi . fn ( ( ) => 'fake-user:fake-key' )
9999} ) ) ;
100- vi . mock ( '../../src/tools/testmanagement-utils/TCG-utils/api' , ( ) => ( {
101- projectIdentifierToId : vi . fn ( ( ) => Promise . resolve ( '999' ) ) ,
102- fetchFormFields : vi . fn ( ) ,
103- normalizeDefaultFieldValue : vi . fn ( ) ,
104- } ) ) ;
100+ vi . mock ( '../../src/tools/testmanagement-utils/TCG-utils/api' , async ( importActual ) => {
101+ const actual = await importActual <
102+ typeof import ( '../../src/tools/testmanagement-utils/TCG-utils/api' )
103+ > ( ) ;
104+ return {
105+ ...actual ,
106+ projectIdentifierToId : vi . fn ( ( ) => Promise . resolve ( '999' ) ) ,
107+ fetchFormFields : vi . fn ( ) ,
108+ normalizeDefaultFieldValue : vi . fn ( ) ,
109+ } ;
110+ } ) ;
105111vi . mock ( 'form-data' , ( ) => {
106112 return {
107113 default : vi . fn ( ) . mockImplementation ( ( ) => ( {
@@ -1077,7 +1083,6 @@ describe('createTestCase — priority normalization', () => {
10771083 let createTestCaseReal : typeof import ( '../../src/tools/testmanagement-utils/create-testcase' ) . createTestCase ;
10781084 let apiClientMock : typeof import ( '../../src/lib/apiClient' ) . apiClient ;
10791085 let fetchFormFieldsMock : Mock ;
1080- let normalizeMock : Mock ;
10811086
10821087 beforeAll ( async ( ) => {
10831088 const actual = await vi . importActual <
@@ -1087,7 +1092,6 @@ describe('createTestCase — priority normalization', () => {
10871092 apiClientMock = ( await import ( '../../src/lib/apiClient' ) ) . apiClient ;
10881093 const api = await import ( '../../src/tools/testmanagement-utils/TCG-utils/api' ) ;
10891094 fetchFormFieldsMock = api . fetchFormFields as unknown as Mock ;
1090- normalizeMock = api . normalizeDefaultFieldValue as unknown as Mock ;
10911095 } ) ;
10921096
10931097 beforeEach ( ( ) => {
@@ -1126,7 +1130,6 @@ describe('createTestCase — priority normalization', () => {
11261130
11271131 it ( 'looks up the project form fields and sends the normalized priority in the request body' , async ( ) => {
11281132 fetchFormFieldsMock . mockResolvedValue ( formFields ) ;
1129- normalizeMock . mockReturnValue ( 'Critical' ) ;
11301133 ( apiClientMock . post as Mock ) . mockResolvedValueOnce ( createSuccess ) ;
11311134
11321135 const result = await createTestCaseReal (
@@ -1135,7 +1138,8 @@ describe('createTestCase — priority normalization', () => {
11351138 ) ;
11361139
11371140 expect ( result . isError ) . toBeFalsy ( ) ;
1138- expect ( normalizeMock ) . toHaveBeenCalledWith ( priorityValues , 'critical' , 'name' ) ;
1141+ // Real normalizeDefaultFields maps the internal name 'critical' to the
1142+ // display name 'Critical' the create endpoint requires.
11391143 const body = ( apiClientMock . post as Mock ) . mock . calls [ 0 ] [ 0 ] . body ;
11401144 expect ( body . test_case . priority ) . toBe ( 'Critical' ) ;
11411145 } ) ;
@@ -1162,6 +1166,72 @@ describe('createTestCase — priority normalization', () => {
11621166 const body = ( apiClientMock . post as Mock ) . mock . calls [ 0 ] [ 0 ] . body ;
11631167 expect ( body . test_case . priority ) . toBe ( 'critical' ) ;
11641168 } ) ;
1169+
1170+ const caseTypeValues = [
1171+ { name : 'Functional' , internal_name : 'functional' , value : 1 } ,
1172+ { name : 'Regression' , internal_name : 'regression' , value : 2 } ,
1173+ ] ;
1174+
1175+ it ( 'looks up the project form fields and sends the normalized case_type in the request body' , async ( ) => {
1176+ fetchFormFieldsMock . mockResolvedValue ( {
1177+ default_fields : { case_type : { values : caseTypeValues } } ,
1178+ custom_fields : { } ,
1179+ } ) ;
1180+ ( apiClientMock . post as Mock ) . mockResolvedValueOnce ( createSuccess ) ;
1181+
1182+ const result = await createTestCaseReal (
1183+ { ...baseArgs , case_type : 'functional' } ,
1184+ mockConfig as any ,
1185+ ) ;
1186+
1187+ expect ( result . isError ) . toBeFalsy ( ) ;
1188+ // Real normalizeDefaultFields maps 'functional' to the display name 'Functional'.
1189+ const body = ( apiClientMock . post as Mock ) . mock . calls [ 0 ] [ 0 ] . body ;
1190+ expect ( body . test_case . case_type ) . toBe ( 'Functional' ) ;
1191+ } ) ;
1192+
1193+ it ( 'omits case_type from the request body when not provided (preserves project default)' , async ( ) => {
1194+ ( apiClientMock . post as Mock ) . mockResolvedValueOnce ( createSuccess ) ;
1195+
1196+ await createTestCaseReal ( { ...baseArgs } , mockConfig as any ) ;
1197+
1198+ const body = ( apiClientMock . post as Mock ) . mock . calls [ 0 ] [ 0 ] . body ;
1199+ expect ( body . test_case ) . not . toHaveProperty ( 'case_type' ) ;
1200+ } ) ;
1201+
1202+ it ( 'passes the raw case_type through when the form-fields lookup fails (graceful fallback)' , async ( ) => {
1203+ fetchFormFieldsMock . mockRejectedValue ( new Error ( 'Network Error' ) ) ;
1204+ ( apiClientMock . post as Mock ) . mockResolvedValueOnce ( createSuccess ) ;
1205+
1206+ await createTestCaseReal (
1207+ { ...baseArgs , case_type : 'functional' } ,
1208+ mockConfig as any ,
1209+ ) ;
1210+
1211+ const body = ( apiClientMock . post as Mock ) . mock . calls [ 0 ] [ 0 ] . body ;
1212+ expect ( body . test_case . case_type ) . toBe ( 'functional' ) ;
1213+ } ) ;
1214+
1215+ it ( 'normalizes both priority and case_type in a single form-fields lookup' , async ( ) => {
1216+ fetchFormFieldsMock . mockResolvedValue ( {
1217+ default_fields : {
1218+ priority : { values : priorityValues } ,
1219+ case_type : { values : caseTypeValues } ,
1220+ } ,
1221+ custom_fields : { } ,
1222+ } ) ;
1223+ ( apiClientMock . post as Mock ) . mockResolvedValueOnce ( createSuccess ) ;
1224+
1225+ await createTestCaseReal (
1226+ { ...baseArgs , priority : 'critical' , case_type : 'functional' } ,
1227+ mockConfig as any ,
1228+ ) ;
1229+
1230+ expect ( fetchFormFieldsMock ) . toHaveBeenCalledTimes ( 1 ) ;
1231+ const body = ( apiClientMock . post as Mock ) . mock . calls [ 0 ] [ 0 ] . body ;
1232+ expect ( body . test_case . priority ) . toBe ( 'Critical' ) ;
1233+ expect ( body . test_case . case_type ) . toBe ( 'Functional' ) ;
1234+ } ) ;
11651235} ) ;
11661236
11671237// Template slug pass-through + multi-select custom fields.
@@ -1340,6 +1410,30 @@ describe('createTestCase — template & multi-select custom_fields', () => {
13401410 expect ( call . body . test_case . folder_id ) . toBeUndefined ( ) ;
13411411 } ) ;
13421412
1413+ // case_type must survive into the v1 test_case body (spread from
1414+ // testCaseParams), normalized to the display name the endpoint accepts.
1415+ it ( 'carries the normalized case_type into the v1 body when template_id is set' , async ( ) => {
1416+ const api = await import ( '../../src/tools/testmanagement-utils/TCG-utils/api' ) ;
1417+ ( api . fetchFormFields as Mock ) . mockResolvedValue ( {
1418+ default_fields : {
1419+ case_type : {
1420+ values : [ { name : 'Functional' , internal_name : 'functional' , value : 1 } ] ,
1421+ } ,
1422+ } ,
1423+ custom_fields : [ ] ,
1424+ } ) ;
1425+ ( apiClientMock . post as Mock ) . mockResolvedValueOnce ( respWithId ( 656127 ) ) ;
1426+
1427+ await createTestCaseReal (
1428+ { ...baseArgs , template_id : 656127 , case_type : 'functional' } ,
1429+ mockConfig as any ,
1430+ ) ;
1431+
1432+ const call = ( apiClientMock . post as Mock ) . mock . calls [ 0 ] [ 0 ] ;
1433+ expect ( call . url ) . toContain ( '/api/v1/projects/' ) ;
1434+ expect ( call . body . test_case . case_type ) . toBe ( 'Functional' ) ;
1435+ } ) ;
1436+
13431437 it ( 'translates custom_fields name→id and option value→id on the v1 path' , async ( ) => {
13441438 const api = await import ( '../../src/tools/testmanagement-utils/TCG-utils/api' ) ;
13451439 ( api . fetchFormFields as Mock ) . mockResolvedValueOnce ( {
0 commit comments