@@ -1100,4 +1100,234 @@ describe("CSV processor", () => {
11001100 }
11011101 ` )
11021102 } )
1103+
1104+ describe ( "System-generated columns" , ( ) => {
1105+ it ( "should ignore product timestamp columns during import" , ( ) => {
1106+ const csvRow : Record < string , string | boolean | number > = {
1107+ "Product Handle" : "test-product" ,
1108+ "Product Title" : "Test Product" ,
1109+ "Product Created At" : "" ,
1110+ "Product Updated At" : "" ,
1111+ "Product Deleted At" : "" ,
1112+ "Product Is Giftcard" : "true" ,
1113+ }
1114+
1115+ const normalized = CSVNormalizer . preProcess ( csvRow , 1 )
1116+ expect ( normalized [ "product created at" ] ) . toBe ( "" )
1117+ expect ( normalized [ "product updated at" ] ) . toBe ( "" )
1118+ expect ( normalized [ "product deleted at" ] ) . toBe ( "" )
1119+ expect ( normalized [ "product is giftcard" ] ) . toBe ( "true" )
1120+
1121+ const processor = new CSVNormalizer ( [ normalized ] )
1122+ const result = processor . proccess ( )
1123+
1124+ // Should be in toCreate since we only have handle
1125+ expect ( result . toCreate [ "test-product" ] ) . toBeDefined ( )
1126+ expect ( result . toCreate [ "test-product" ] . is_giftcard ) . toBe ( true )
1127+
1128+ // Timestamp fields should not be in the output since they're ignored
1129+ expect ( result . toCreate [ "test-product" ] [ "created_at" ] ) . toBeUndefined ( )
1130+ expect ( result . toCreate [ "test-product" ] [ "updated_at" ] ) . toBeUndefined ( )
1131+ expect ( result . toCreate [ "test-product" ] [ "deleted_at" ] ) . toBeUndefined ( )
1132+
1133+ // Verify that the timestamp fields are present in normalized data but ignored during processing
1134+ expect ( normalized [ "product created at" ] ) . toBe ( "" )
1135+ expect ( normalized [ "product updated at" ] ) . toBe ( "" )
1136+ expect ( normalized [ "product deleted at" ] ) . toBe ( "" )
1137+ } )
1138+
1139+ it ( "should ignore variant timestamp columns during import" , ( ) => {
1140+ const csvRow : Record < string , string | boolean | number > = {
1141+ "Product Handle" : "test-product" ,
1142+ "Product Title" : "Test Product" ,
1143+ "Variant Title" : "Test Variant" ,
1144+ "Variant SKU" : "TEST-SKU" ,
1145+ "Variant Created At" : "" ,
1146+ "Variant Updated At" : "" ,
1147+ "Variant Deleted At" : "" ,
1148+ "Variant Product Id" : "prod_123" ,
1149+ }
1150+
1151+ const normalized = CSVNormalizer . preProcess ( csvRow , 1 )
1152+ expect ( normalized [ "variant created at" ] ) . toBe ( "" )
1153+ expect ( normalized [ "variant updated at" ] ) . toBe ( "" )
1154+ expect ( normalized [ "variant deleted at" ] ) . toBe ( "" )
1155+ expect ( normalized [ "variant product id" ] ) . toBe ( "prod_123" )
1156+
1157+ const processor = new CSVNormalizer ( [ normalized ] )
1158+ const result = processor . proccess ( )
1159+
1160+ // Should be in toCreate since we only have handle
1161+ expect ( result . toCreate [ "test-product" ] ) . toBeDefined ( )
1162+ expect ( result . toCreate [ "test-product" ] . variants ) . toHaveLength ( 1 )
1163+
1164+ const variant = result . toCreate [ "test-product" ] . variants [ 0 ]
1165+ expect ( variant . title ) . toBe ( "Test Variant" )
1166+ expect ( variant . sku ) . toBe ( "TEST-SKU" )
1167+
1168+ // Timestamp fields should not be in the variant output since they're ignored
1169+ expect ( variant [ "created_at" ] ) . toBeUndefined ( )
1170+ expect ( variant [ "updated_at" ] ) . toBeUndefined ( )
1171+ expect ( variant [ "deleted_at" ] ) . toBeUndefined ( )
1172+ expect ( variant [ "product_id" ] ) . toBeUndefined ( )
1173+
1174+ // Verify that the timestamp fields are present in normalized data but ignored during processing
1175+ expect ( normalized [ "variant created at" ] ) . toBe ( "" )
1176+ expect ( normalized [ "variant updated at" ] ) . toBe ( "" )
1177+ expect ( normalized [ "variant deleted at" ] ) . toBe ( "" )
1178+ expect ( normalized [ "variant product id" ] ) . toBe ( "prod_123" )
1179+ } )
1180+
1181+ it ( "should process product is giftcard as boolean correctly" , ( ) => {
1182+ const csvRow = {
1183+ "Product Handle" : "giftcard-product" ,
1184+ "Product Title" : "Gift Card" ,
1185+ "Product Is Giftcard" : "true" ,
1186+ }
1187+
1188+ const normalized = CSVNormalizer . preProcess ( csvRow , 1 )
1189+ const processor = new CSVNormalizer ( [ normalized ] )
1190+ const result = processor . proccess ( )
1191+
1192+ expect ( result . toCreate [ "giftcard-product" ] . is_giftcard ) . toBe ( true )
1193+ } )
1194+
1195+ it ( "should process product is giftcard as false correctly" , ( ) => {
1196+ const csvRow = {
1197+ "Product Handle" : "regular-product" ,
1198+ "Product Title" : "Regular Product" ,
1199+ "Product Is Giftcard" : "false" ,
1200+ }
1201+
1202+ const normalized = CSVNormalizer . preProcess ( csvRow , 1 )
1203+ const processor = new CSVNormalizer ( [ normalized ] )
1204+ const result = processor . proccess ( )
1205+
1206+ expect ( result . toCreate [ "regular-product" ] . is_giftcard ) . toBe ( false )
1207+ } )
1208+
1209+ it ( "should handle product is giftcard with various truthy/falsy values" , ( ) => {
1210+ const testCases = [
1211+ { value : "true" , expected : true } ,
1212+ { value : "false" , expected : false } ,
1213+ { value : "TRUE" , expected : true } ,
1214+ { value : "FALSE" , expected : false } ,
1215+ ]
1216+
1217+ testCases . forEach ( ( { value, expected } ) => {
1218+ const csvRow = {
1219+ "Product Handle" : `test-product-${ value } ` ,
1220+ "Product Title" : "Test Product" ,
1221+ "Product Is Giftcard" : value ,
1222+ }
1223+
1224+ const normalized = CSVNormalizer . preProcess ( csvRow , 1 )
1225+ const processor = new CSVNormalizer ( [ normalized ] )
1226+ const result = processor . proccess ( )
1227+
1228+ expect ( result . toCreate [ `test-product-${ value } ` ] . is_giftcard ) . toBe ( expected )
1229+ } )
1230+ } )
1231+ } )
1232+
1233+ describe ( "Column validation" , ( ) => {
1234+ it ( "should accept all system-generated columns without error" , ( ) => {
1235+ const csvRow : Record < string , string | boolean | number > = {
1236+ "Product Handle" : "test-product" ,
1237+ "Product Title" : "Test Product" ,
1238+ "Product Created At" : "" ,
1239+ "Product Updated At" : "" ,
1240+ "Product Deleted At" : "" ,
1241+ "Product Is Giftcard" : "true" ,
1242+ "Variant Title" : "Test Variant" ,
1243+ "Variant Created At" : "" ,
1244+ "Variant Updated At" : "" ,
1245+ "Variant Deleted At" : "" ,
1246+ "Variant Product Id" : "prod_123" ,
1247+ }
1248+
1249+ expect ( ( ) => CSVNormalizer . preProcess ( csvRow , 1 ) ) . not . toThrow ( )
1250+ } )
1251+
1252+ it ( "should still reject truly unknown columns" , ( ) => {
1253+ const csvRow = {
1254+ "Product Handle" : "test-product" ,
1255+ "Product Title" : "Test Product" ,
1256+ "Unknown Column" : "some value" ,
1257+ }
1258+
1259+ expect ( ( ) => CSVNormalizer . preProcess ( csvRow , 1 ) ) . toThrow (
1260+ 'Invalid column name(s) "Unknown Column"'
1261+ )
1262+ } )
1263+
1264+ it ( "should handle mixed case column names correctly" , ( ) => {
1265+ const csvRow = {
1266+ "PRODUCT HANDLE" : "test-product" ,
1267+ "Product Title" : "Test Product" ,
1268+ "PRODUCT IS GIFTCARD" : "true" ,
1269+ "Variant Created At" : "2024-01-01T00:00:00Z" ,
1270+ }
1271+
1272+ const normalized = CSVNormalizer . preProcess ( csvRow , 1 )
1273+ expect ( normalized [ "product handle" ] ) . toBe ( "test-product" )
1274+ expect ( normalized [ "product is giftcard" ] ) . toBe ( "true" )
1275+ expect ( normalized [ "variant created at" ] ) . toBe ( "2024-01-01T00:00:00Z" )
1276+ } )
1277+ } )
1278+
1279+ describe ( "Edge cases" , ( ) => {
1280+ it ( "should handle empty timestamp values" , ( ) => {
1281+ const csvRow : Record < string , string | boolean | number > = {
1282+ "Product Handle" : "test-product" ,
1283+ "Product Title" : "Test Product" ,
1284+ "Product Created At" : "" ,
1285+ "Product Updated At" : "" ,
1286+ "Product Deleted At" : "" ,
1287+ }
1288+
1289+ const normalized = CSVNormalizer . preProcess ( csvRow , 1 )
1290+ expect ( normalized [ "product created at" ] ) . toBe ( "" )
1291+ expect ( normalized [ "product updated at" ] ) . toBe ( "" )
1292+ expect ( normalized [ "product deleted at" ] ) . toBe ( "" )
1293+
1294+ const processor = new CSVNormalizer ( [ normalized ] )
1295+ const result = processor . proccess ( )
1296+ expect ( result . toCreate [ "test-product" ] ) . toBeDefined ( )
1297+ } )
1298+
1299+ it ( "should handle products with only ID (no handle) correctly" , ( ) => {
1300+ const csvRow = {
1301+ "Product Id" : "prod_123" ,
1302+ "Product Title" : "Test Product" ,
1303+ "Product Is Giftcard" : "true" ,
1304+ }
1305+
1306+ const normalized = CSVNormalizer . preProcess ( csvRow , 1 )
1307+ const processor = new CSVNormalizer ( [ normalized ] )
1308+ const result = processor . proccess ( )
1309+
1310+ // Should be in toUpdate since we have an ID
1311+ expect ( result . toUpdate [ "prod_123" ] ) . toBeDefined ( )
1312+ expect ( result . toUpdate [ "prod_123" ] . is_giftcard ) . toBe ( true )
1313+ } )
1314+
1315+ it ( "should handle products with both ID and handle correctly" , ( ) => {
1316+ const csvRow = {
1317+ "Product Id" : "prod_123" ,
1318+ "Product Handle" : "test-product" ,
1319+ "Product Title" : "Test Product" ,
1320+ "Product Is Giftcard" : "true" ,
1321+ }
1322+
1323+ const normalized = CSVNormalizer . preProcess ( csvRow , 1 )
1324+ const processor = new CSVNormalizer ( [ normalized ] )
1325+ const result = processor . proccess ( )
1326+
1327+ // Should be in toUpdate since we have an ID
1328+ expect ( result . toUpdate [ "prod_123" ] ) . toBeDefined ( )
1329+ expect ( result . toUpdate [ "prod_123" ] . is_giftcard ) . toBe ( true )
1330+ expect ( result . toCreate [ "test-product" ] ) . toBeUndefined ( )
1331+ } )
1332+ } )
11031333} )
0 commit comments