Skip to content

Commit db1cffa

Browse files
committed
AG-42731 Handle correctly null as targetObject in isKeyInObject helper.
Squashed commit of the following: commit a249f71 Author: Slava Leleka <[email protected]> Date: Tue May 27 15:59:23 2025 +0300 Update changelog commit d2d844e Author: Slava Leleka <[email protected]> Date: Tue May 27 15:41:40 2025 +0300 Update changelog commit 0fc89ac Author: Adam Wróblewski <[email protected]> Date: Tue May 27 10:44:59 2025 +0200 Fix changelog commit 2da230d Author: Adam Wróblewski <[email protected]> Date: Tue May 27 10:00:05 2025 +0200 Handle correctly `null` as `targetObject` in `isKeyInObject` helper
1 parent 21470ee commit db1cffa

File tree

3 files changed

+286
-0
lines changed

3 files changed

+286
-0
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@ The format is based on [Keep a Changelog], and this project adheres to [Semantic
1010
<!-- TODO: change `@added unknown` tag due to the actual version -->
1111
<!-- during new scriptlets or redirects releasing -->
1212

13+
## [Unreleased]
14+
15+
### Fixed
16+
17+
- `json-prune` scriptlet to properly handle `null` values
18+
while checking specified key in object [#504].
19+
20+
[Unreleased]: https://github.com/AdguardTeam/Scriptlets/compare/v2.2.4...HEAD
21+
[#504]: https://github.com/AdguardTeam/Scriptlets/issues/504
22+
1323
## [v2.2.4] - 2025-05-23
1424

1525
### Changed

src/helpers/get-wildcard-property-in-chain.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ export function isKeyInObject(baseObj: ChainBase, path: string, valueToCheck: an
1919
* @returns `true` if the path exists and matches the value (if provided), otherwise `false`.
2020
*/
2121
const check = (targetObject: ChainBase, pathSegments: string[]): boolean => {
22+
if (targetObject === undefined || targetObject === null) {
23+
return false;
24+
}
25+
2226
if (pathSegments.length === 0) {
2327
if (valueToCheck !== undefined) {
2428
if (typeof targetObject === 'string' && valueToCheck instanceof RegExp) {

tests/helpers/prune-utils.spec.js

Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -957,4 +957,276 @@ describe('jsonPruner tests', () => {
957957

958958
expect(result).toStrictEqual(expected);
959959
});
960+
961+
// eslint-disable-next-line max-len
962+
test('Removes recommendation items with "adClickLog" containing "clickUrl" property when in other cases "adClickLog" is "null"', async () => {
963+
const root = [
964+
{
965+
data: {
966+
poiRecommendations: {
967+
chips: null,
968+
recommendations: [
969+
{
970+
recommendType: 'similar',
971+
category: 'restaurant',
972+
items: [
973+
{
974+
title: 'Test',
975+
imageUrls: [
976+
{
977+
rank: 1,
978+
url: 'https://example.org/image1.jpg',
979+
__typename: 'RecommendationImageUrl',
980+
},
981+
],
982+
reviewCount: 2216,
983+
adId: null,
984+
impressionEventUrl: null,
985+
adClickLog: null,
986+
adDescription: null,
987+
distance: '220m',
988+
__typename: 'RecommendationItem',
989+
},
990+
{
991+
title: 'Test',
992+
imageUrls: [
993+
{
994+
rank: 1,
995+
url: 'https://example.org/image1.jpg',
996+
__typename: 'RecommendationImageUrl',
997+
},
998+
],
999+
reviewCount: 852,
1000+
adId: null,
1001+
impressionEventUrl: null,
1002+
adClickLog: {
1003+
clickUrl: 'https://example.org/ad_click',
1004+
},
1005+
adDescription: null,
1006+
distance: '190m',
1007+
__typename: 'RecommendationItem',
1008+
},
1009+
{
1010+
title: 'Test',
1011+
imageUrls: [
1012+
{
1013+
rank: 1,
1014+
url: 'https://example.org/image1.jpg',
1015+
__typename: 'RecommendationImageUrl',
1016+
},
1017+
],
1018+
reviewCount: 809,
1019+
adId: null,
1020+
impressionEventUrl: null,
1021+
adClickLog: null,
1022+
adDescription: null,
1023+
distance: '30m',
1024+
__typename: 'RecommendationItem',
1025+
},
1026+
],
1027+
__typename: 'PoiRecommendation',
1028+
},
1029+
{
1030+
recommendType: 'next',
1031+
category: 'cafe',
1032+
items: [
1033+
{
1034+
title: 'Test',
1035+
imageUrls: [
1036+
{
1037+
rank: 1,
1038+
url: 'https://example.org/image1.jpg',
1039+
__typename: 'RecommendationImageUrl',
1040+
},
1041+
],
1042+
reviewCount: 3564,
1043+
adId: null,
1044+
impressionEventUrl: null,
1045+
adClickLog: 1,
1046+
adDescription: null,
1047+
distance: '2.7km',
1048+
__typename: 'RecommendationItem',
1049+
},
1050+
{
1051+
title: 'Test',
1052+
imageUrls: [
1053+
{
1054+
rank: 1,
1055+
url: 'https://example.org/image1.jpg',
1056+
__typename: 'RecommendationImageUrl',
1057+
},
1058+
],
1059+
reviewCount: 91,
1060+
adId: null,
1061+
impressionEventUrl: null,
1062+
adClickLog: {
1063+
clickUrl: 'https://example.org/ad_click',
1064+
},
1065+
adDescription: null,
1066+
distance: '960m',
1067+
__typename: 'RecommendationItem',
1068+
},
1069+
{
1070+
title: 'Test',
1071+
imageUrls: [
1072+
{
1073+
rank: 1,
1074+
url: 'https://example.org/image1.jpg',
1075+
__typename: 'RecommendationImageUrl',
1076+
},
1077+
],
1078+
reviewCount: 122,
1079+
adId: null,
1080+
impressionEventUrl: null,
1081+
adClickLog: null,
1082+
adDescription: null,
1083+
distance: '720m',
1084+
__typename: 'RecommendationItem',
1085+
},
1086+
{
1087+
title: 'Test',
1088+
imageUrls: [
1089+
{
1090+
rank: 1,
1091+
url: 'https://example.org/image1.jpg',
1092+
__typename: 'RecommendationImageUrl',
1093+
},
1094+
],
1095+
reviewCount: 109,
1096+
adId: null,
1097+
impressionEventUrl: null,
1098+
adClickLog: null,
1099+
adDescription: null,
1100+
distance: '720m',
1101+
__typename: 'RecommendationItem',
1102+
},
1103+
],
1104+
__typename: 'PoiRecommendation',
1105+
},
1106+
],
1107+
__typename: 'PoiRecommendationsResult',
1108+
},
1109+
},
1110+
},
1111+
];
1112+
1113+
const expected = [
1114+
{
1115+
data: {
1116+
poiRecommendations: {
1117+
chips: null,
1118+
recommendations: [
1119+
{
1120+
recommendType: 'similar',
1121+
category: 'restaurant',
1122+
items: [
1123+
{
1124+
title: 'Test',
1125+
imageUrls: [
1126+
{
1127+
rank: 1,
1128+
url: 'https://example.org/image1.jpg',
1129+
__typename: 'RecommendationImageUrl',
1130+
},
1131+
],
1132+
reviewCount: 2216,
1133+
adId: null,
1134+
impressionEventUrl: null,
1135+
adClickLog: null,
1136+
adDescription: null,
1137+
distance: '220m',
1138+
__typename: 'RecommendationItem',
1139+
},
1140+
{
1141+
title: 'Test',
1142+
imageUrls: [
1143+
{
1144+
rank: 1,
1145+
url: 'https://example.org/image1.jpg',
1146+
__typename: 'RecommendationImageUrl',
1147+
},
1148+
],
1149+
reviewCount: 809,
1150+
adId: null,
1151+
impressionEventUrl: null,
1152+
adClickLog: null,
1153+
adDescription: null,
1154+
distance: '30m',
1155+
__typename: 'RecommendationItem',
1156+
},
1157+
],
1158+
__typename: 'PoiRecommendation',
1159+
},
1160+
{
1161+
recommendType: 'next',
1162+
category: 'cafe',
1163+
items: [
1164+
{
1165+
title: 'Test',
1166+
imageUrls: [
1167+
{
1168+
rank: 1,
1169+
url: 'https://example.org/image1.jpg',
1170+
__typename: 'RecommendationImageUrl',
1171+
},
1172+
],
1173+
reviewCount: 3564,
1174+
adId: null,
1175+
impressionEventUrl: null,
1176+
adClickLog: 1,
1177+
adDescription: null,
1178+
distance: '2.7km',
1179+
__typename: 'RecommendationItem',
1180+
},
1181+
{
1182+
title: 'Test',
1183+
imageUrls: [
1184+
{
1185+
rank: 1,
1186+
url: 'https://example.org/image1.jpg',
1187+
__typename: 'RecommendationImageUrl',
1188+
},
1189+
],
1190+
reviewCount: 122,
1191+
adId: null,
1192+
impressionEventUrl: null,
1193+
adClickLog: null,
1194+
adDescription: null,
1195+
distance: '720m',
1196+
__typename: 'RecommendationItem',
1197+
},
1198+
{
1199+
title: 'Test',
1200+
imageUrls: [
1201+
{
1202+
rank: 1,
1203+
url: 'https://example.org/image1.jpg',
1204+
__typename: 'RecommendationImageUrl',
1205+
},
1206+
],
1207+
reviewCount: 109,
1208+
adId: null,
1209+
impressionEventUrl: null,
1210+
adClickLog: null,
1211+
adDescription: null,
1212+
distance: '720m',
1213+
__typename: 'RecommendationItem',
1214+
},
1215+
],
1216+
__typename: 'PoiRecommendation',
1217+
},
1218+
],
1219+
__typename: 'PoiRecommendationsResult',
1220+
},
1221+
},
1222+
},
1223+
];
1224+
1225+
const pathToPrune = getPrunePath('[].data.poiRecommendations.recommendations.[].items.[-].adClickLog.clickUrl');
1226+
const requiredPaths = getPrunePath('');
1227+
const stack = '';
1228+
const result = jsonPruner(name, root, pathToPrune, requiredPaths, stack, nativeObjects);
1229+
1230+
expect(result).toStrictEqual(expected);
1231+
});
9601232
});

0 commit comments

Comments
 (0)