@adtrackify/at-service-common 4.0.22 → 4.0.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/cjs/__tests__/helpers/public-api-response-helper.spec.js +61 -0
  2. package/dist/cjs/__tests__/helpers/public-api-response-helper.spec.js.map +1 -0
  3. package/dist/cjs/clients/generic/dynamodb-client.d.ts +0 -4
  4. package/dist/cjs/clients/generic/dynamodb-client.js +0 -21
  5. package/dist/cjs/clients/generic/dynamodb-client.js.map +1 -1
  6. package/dist/cjs/helpers/index.d.ts +1 -0
  7. package/dist/cjs/helpers/index.js +1 -0
  8. package/dist/cjs/helpers/index.js.map +1 -1
  9. package/dist/cjs/helpers/public-api-response-helper.d.ts +21 -0
  10. package/dist/cjs/helpers/public-api-response-helper.js +46 -0
  11. package/dist/cjs/helpers/public-api-response-helper.js.map +1 -0
  12. package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.d.ts +1 -5
  13. package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js +21 -110
  14. package/dist/cjs/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js.map +1 -1
  15. package/dist/cjs/types/index.d.ts +1 -0
  16. package/dist/cjs/types/index.js +1 -0
  17. package/dist/cjs/types/index.js.map +1 -1
  18. package/dist/cjs/types/public-api-types.d.ts +24 -0
  19. package/dist/cjs/types/public-api-types.js +14 -0
  20. package/dist/cjs/types/public-api-types.js.map +1 -0
  21. package/dist/esm/__tests__/helpers/public-api-response-helper.spec.js +56 -0
  22. package/dist/esm/__tests__/helpers/public-api-response-helper.spec.js.map +1 -0
  23. package/dist/esm/clients/generic/dynamodb-client.d.ts +0 -4
  24. package/dist/esm/clients/generic/dynamodb-client.js +0 -21
  25. package/dist/esm/clients/generic/dynamodb-client.js.map +1 -1
  26. package/dist/esm/helpers/index.d.ts +1 -0
  27. package/dist/esm/helpers/index.js +1 -0
  28. package/dist/esm/helpers/index.js.map +1 -1
  29. package/dist/esm/helpers/public-api-response-helper.d.ts +21 -0
  30. package/dist/esm/helpers/public-api-response-helper.js +39 -0
  31. package/dist/esm/helpers/public-api-response-helper.js.map +1 -0
  32. package/dist/esm/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.d.ts +1 -5
  33. package/dist/esm/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js +21 -110
  34. package/dist/esm/services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js.map +1 -1
  35. package/dist/esm/types/index.d.ts +1 -0
  36. package/dist/esm/types/index.js +1 -0
  37. package/dist/esm/types/index.js.map +1 -1
  38. package/dist/esm/types/public-api-types.d.ts +24 -0
  39. package/dist/esm/types/public-api-types.js +11 -0
  40. package/dist/esm/types/public-api-types.js.map +1 -0
  41. package/package.json +1 -1
  42. package/dist/cjs/__tests__/identity-cache/identity-traits-merge-write.spec.js +0 -175
  43. package/dist/cjs/__tests__/identity-cache/identity-traits-merge-write.spec.js.map +0 -1
  44. package/dist/esm/__tests__/identity-cache/identity-traits-merge-write.spec.js +0 -173
  45. package/dist/esm/__tests__/identity-cache/identity-traits-merge-write.spec.js.map +0 -1
  46. /package/dist/cjs/__tests__/{identity-cache/identity-traits-merge-write.spec.d.ts → helpers/public-api-response-helper.spec.d.ts} +0 -0
  47. /package/dist/esm/__tests__/{identity-cache/identity-traits-merge-write.spec.d.ts → helpers/public-api-response-helper.spec.d.ts} +0 -0
@@ -1,175 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- jest.mock('../../clients/index.js', () => ({
4
- DynamoDbClient: {
5
- safeGet: jest.fn(),
6
- safePut: jest.fn(),
7
- safeDelete: jest.fn(),
8
- safeBatchGet: jest.fn(),
9
- safeBatchWrite: jest.fn(),
10
- safeQueryByGSI: jest.fn(),
11
- batchWrite: jest.fn(),
12
- conditionalPut: jest.fn(),
13
- },
14
- }));
15
- jest.mock('../../helpers/index.js', () => ({
16
- Logger: {
17
- debug: jest.fn(),
18
- info: jest.fn(),
19
- warn: jest.fn(),
20
- error: jest.fn(),
21
- },
22
- }));
23
- const identity_cache_dynamodb_db_service_js_1 = require("../../services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js");
24
- const index_js_1 = require("../../clients/index.js");
25
- const mockedDynamoDbClient = index_js_1.DynamoDbClient;
26
- const pixelId = 'pixel-123';
27
- const identityId = 'identity-abc';
28
- const buildRecord = (traits, updatedAt) => ({
29
- pk: `identity#${pixelId}#${identityId}`,
30
- pixelId,
31
- identityId,
32
- response: { identityId, traits },
33
- updatedAt,
34
- });
35
- beforeEach(() => {
36
- jest.clearAllMocks();
37
- mockedDynamoDbClient.conditionalPut.mockResolvedValue({ success: true, conditionFailed: false });
38
- mockedDynamoDbClient.safeBatchWrite.mockResolvedValue(undefined);
39
- });
40
- describe('getTraitsByIdentityId', () => {
41
- it('returns the traits from the identity# record', async () => {
42
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(buildRecord({ emails: ['a@x.com'] }, 'T1'));
43
- const traits = await identity_cache_dynamodb_db_service_js_1.IdentityCacheDynamoDbDbService.getTraitsByIdentityId(pixelId, identityId);
44
- expect(traits).toEqual({ emails: ['a@x.com'] });
45
- expect(mockedDynamoDbClient.safeGet).toHaveBeenCalledWith(expect.any(String), 'pk', `identity#${pixelId}#${identityId}`);
46
- });
47
- it('returns undefined when there is no record (cold)', async () => {
48
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
49
- expect(await identity_cache_dynamodb_db_service_js_1.IdentityCacheDynamoDbDbService.getTraitsByIdentityId(pixelId, identityId)).toBeUndefined();
50
- });
51
- it('returns undefined when params are missing', async () => {
52
- expect(await identity_cache_dynamodb_db_service_js_1.IdentityCacheDynamoDbDbService.getTraitsByIdentityId('', identityId)).toBeUndefined();
53
- expect(await identity_cache_dynamodb_db_service_js_1.IdentityCacheDynamoDbDbService.getTraitsByIdentityId(pixelId, '')).toBeUndefined();
54
- expect(mockedDynamoDbClient.safeGet).not.toHaveBeenCalled();
55
- });
56
- });
57
- describe('mergeTraitsIntoIdentityCache', () => {
58
- it('cold record: writes with attribute_not_exists(pk) and returns incoming traits', async () => {
59
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
60
- const result = await identity_cache_dynamodb_db_service_js_1.IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, {
61
- identityId,
62
- traits: { emails: ['new@x.com'] },
63
- });
64
- expect(result?.identityId).toBe(identityId);
65
- expect(result?.traits?.emails).toEqual(['new@x.com']);
66
- const [, item, condition, values] = mockedDynamoDbClient.conditionalPut.mock.calls[0];
67
- expect(item.pk).toBe(`identity#${pixelId}#${identityId}`);
68
- expect(condition).toBe('attribute_not_exists(pk)');
69
- expect(values).toBeUndefined();
70
- });
71
- it('preserves caller identity metadata (cold: full write; warm: caller wins)', async () => {
72
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
73
- const cold = await identity_cache_dynamodb_db_service_js_1.IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, {
74
- identityId,
75
- traits: { emails: ['a@x.com'] },
76
- isPrimaryV2: true,
77
- version: '2',
78
- });
79
- expect(cold?.isPrimaryV2).toBe(true);
80
- expect(cold?.version).toBe('2');
81
- const stored = buildRecord({ emails: ['old@x.com'] }, 'T1');
82
- stored.response.isPrimaryV2 = false;
83
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(stored);
84
- const warm = await identity_cache_dynamodb_db_service_js_1.IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, {
85
- identityId,
86
- traits: { emails: ['new@x.com'] },
87
- isPrimaryV2: true,
88
- });
89
- expect(warm?.isPrimaryV2).toBe(true);
90
- expect(warm?.traits?.emails?.sort()).toEqual(['new@x.com', 'old@x.com']);
91
- });
92
- it('warm record: unions incoming with current and guards on the read updatedAt', async () => {
93
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(buildRecord({ emails: ['old@x.com'], phones: ['111'] }, 'T1'));
94
- const result = await identity_cache_dynamodb_db_service_js_1.IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, {
95
- identityId,
96
- traits: { emails: ['new@x.com'] },
97
- });
98
- expect(result?.traits?.emails?.sort()).toEqual(['new@x.com', 'old@x.com']);
99
- expect(result?.traits?.phones).toEqual(['111']);
100
- const [, , condition, values] = mockedDynamoDbClient.conditionalPut.mock.calls[0];
101
- expect(condition).toBe('updatedAt = :expectedUpdatedAt');
102
- expect(values).toEqual({ ':expectedUpdatedAt': 'T1' });
103
- });
104
- it('also refreshes the email pointer records', async () => {
105
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
106
- await identity_cache_dynamodb_db_service_js_1.IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, { identityId, traits: { emails: ['p@x.com'] } });
107
- expect(mockedDynamoDbClient.safeBatchWrite).toHaveBeenCalledTimes(1);
108
- const [, pointerItems] = mockedDynamoDbClient.safeBatchWrite.mock.calls[0];
109
- expect(pointerItems[0].pk).toBe(`email#${pixelId}#p@x.com`);
110
- });
111
- it('is order-independent: (A then B) equals (B then A)', async () => {
112
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
113
- const a = await identity_cache_dynamodb_db_service_js_1.IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, { identityId, traits: { emails: ['a@x.com'] } });
114
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(buildRecord((a?.traits ?? {}), 'T1'));
115
- const ab = await identity_cache_dynamodb_db_service_js_1.IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, { identityId, traits: { emails: ['b@x.com'] } });
116
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
117
- const b = await identity_cache_dynamodb_db_service_js_1.IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, { identityId, traits: { emails: ['b@x.com'] } });
118
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(buildRecord((b?.traits ?? {}), 'T1'));
119
- const ba = await identity_cache_dynamodb_db_service_js_1.IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, { identityId, traits: { emails: ['a@x.com'] } });
120
- expect(ab?.traits?.emails?.sort()).toEqual(ba?.traits?.emails?.sort());
121
- expect(ab?.traits?.emails?.sort()).toEqual(['a@x.com', 'b@x.com']);
122
- });
123
- it('retries on a write conflict then succeeds', async () => {
124
- mockedDynamoDbClient.safeGet
125
- .mockResolvedValueOnce(buildRecord({ emails: ['old@x.com'] }, 'T1'))
126
- .mockResolvedValueOnce(buildRecord({ emails: ['old@x.com'], other: ['raced'] }, 'T2'));
127
- mockedDynamoDbClient.conditionalPut
128
- .mockResolvedValueOnce({ success: false, conditionFailed: true })
129
- .mockResolvedValueOnce({ success: true, conditionFailed: false });
130
- const result = await identity_cache_dynamodb_db_service_js_1.IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, {
131
- identityId,
132
- traits: { emails: ['new@x.com'] },
133
- });
134
- expect(mockedDynamoDbClient.conditionalPut).toHaveBeenCalledTimes(2);
135
- expect(result?.traits?.emails?.sort()).toEqual(['new@x.com', 'old@x.com']);
136
- expect(mockedDynamoDbClient.conditionalPut.mock.calls[1][3]).toEqual({ ':expectedUpdatedAt': 'T2' });
137
- });
138
- it('returns undefined after exhausting retries on persistent conflict', async () => {
139
- mockedDynamoDbClient.safeGet.mockResolvedValue(buildRecord({ emails: ['old@x.com'] }, 'T1'));
140
- mockedDynamoDbClient.conditionalPut.mockResolvedValue({ success: false, conditionFailed: true });
141
- const result = await identity_cache_dynamodb_db_service_js_1.IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, {
142
- identityId,
143
- traits: { emails: ['new@x.com'] },
144
- });
145
- expect(result).toBeUndefined();
146
- expect(mockedDynamoDbClient.conditionalPut).toHaveBeenCalledTimes(3);
147
- });
148
- it('stops immediately (no retry) on a hard write error', async () => {
149
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
150
- mockedDynamoDbClient.conditionalPut.mockResolvedValueOnce({ success: false, conditionFailed: false });
151
- const result = await identity_cache_dynamodb_db_service_js_1.IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, {
152
- identityId,
153
- traits: { emails: ['new@x.com'] },
154
- });
155
- expect(result).toBeUndefined();
156
- expect(mockedDynamoDbClient.conditionalPut).toHaveBeenCalledTimes(1);
157
- });
158
- it('returns undefined when params are missing', async () => {
159
- expect(await identity_cache_dynamodb_db_service_js_1.IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache('', { identityId, traits: {} })).toBeUndefined();
160
- expect(await identity_cache_dynamodb_db_service_js_1.IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, { identityId: '', traits: {} })).toBeUndefined();
161
- expect(mockedDynamoDbClient.conditionalPut).not.toHaveBeenCalled();
162
- });
163
- });
164
- describe('updateIdentityCache (regression via shared item-builder)', () => {
165
- it('batch-writes the identity# record plus one email pointer', async () => {
166
- const response = { identityId, traits: { emails: ['a@x.com'] } };
167
- await identity_cache_dynamodb_db_service_js_1.IdentityCacheDynamoDbDbService.updateIdentityCache(pixelId, response);
168
- const [, items] = mockedDynamoDbClient.safeBatchWrite.mock.calls[0];
169
- expect(items).toHaveLength(2);
170
- expect(items[0].pk).toBe(`identity#${pixelId}#${identityId}`);
171
- expect(items[0].response).toEqual(response);
172
- expect(items[1].pk).toBe(`email#${pixelId}#a@x.com`);
173
- });
174
- });
175
- //# sourceMappingURL=identity-traits-merge-write.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"identity-traits-merge-write.spec.js","sourceRoot":"","sources":["../../../../src/__tests__/identity-cache/identity-traits-merge-write.spec.ts"],"names":[],"mappings":"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"}
@@ -1,173 +0,0 @@
1
- jest.mock('../../clients/index.js', () => ({
2
- DynamoDbClient: {
3
- safeGet: jest.fn(),
4
- safePut: jest.fn(),
5
- safeDelete: jest.fn(),
6
- safeBatchGet: jest.fn(),
7
- safeBatchWrite: jest.fn(),
8
- safeQueryByGSI: jest.fn(),
9
- batchWrite: jest.fn(),
10
- conditionalPut: jest.fn(),
11
- },
12
- }));
13
- jest.mock('../../helpers/index.js', () => ({
14
- Logger: {
15
- debug: jest.fn(),
16
- info: jest.fn(),
17
- warn: jest.fn(),
18
- error: jest.fn(),
19
- },
20
- }));
21
- import { IdentityCacheDynamoDbDbService } from '../../services/db/identity-cache-dynamodb-service/identity-cache-dynamodb-db-service.js';
22
- import { DynamoDbClient } from '../../clients/index.js';
23
- const mockedDynamoDbClient = DynamoDbClient;
24
- const pixelId = 'pixel-123';
25
- const identityId = 'identity-abc';
26
- const buildRecord = (traits, updatedAt) => ({
27
- pk: `identity#${pixelId}#${identityId}`,
28
- pixelId,
29
- identityId,
30
- response: { identityId, traits },
31
- updatedAt,
32
- });
33
- beforeEach(() => {
34
- jest.clearAllMocks();
35
- mockedDynamoDbClient.conditionalPut.mockResolvedValue({ success: true, conditionFailed: false });
36
- mockedDynamoDbClient.safeBatchWrite.mockResolvedValue(undefined);
37
- });
38
- describe('getTraitsByIdentityId', () => {
39
- it('returns the traits from the identity# record', async () => {
40
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(buildRecord({ emails: ['a@x.com'] }, 'T1'));
41
- const traits = await IdentityCacheDynamoDbDbService.getTraitsByIdentityId(pixelId, identityId);
42
- expect(traits).toEqual({ emails: ['a@x.com'] });
43
- expect(mockedDynamoDbClient.safeGet).toHaveBeenCalledWith(expect.any(String), 'pk', `identity#${pixelId}#${identityId}`);
44
- });
45
- it('returns undefined when there is no record (cold)', async () => {
46
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
47
- expect(await IdentityCacheDynamoDbDbService.getTraitsByIdentityId(pixelId, identityId)).toBeUndefined();
48
- });
49
- it('returns undefined when params are missing', async () => {
50
- expect(await IdentityCacheDynamoDbDbService.getTraitsByIdentityId('', identityId)).toBeUndefined();
51
- expect(await IdentityCacheDynamoDbDbService.getTraitsByIdentityId(pixelId, '')).toBeUndefined();
52
- expect(mockedDynamoDbClient.safeGet).not.toHaveBeenCalled();
53
- });
54
- });
55
- describe('mergeTraitsIntoIdentityCache', () => {
56
- it('cold record: writes with attribute_not_exists(pk) and returns incoming traits', async () => {
57
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
58
- const result = await IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, {
59
- identityId,
60
- traits: { emails: ['new@x.com'] },
61
- });
62
- expect(result?.identityId).toBe(identityId);
63
- expect(result?.traits?.emails).toEqual(['new@x.com']);
64
- const [, item, condition, values] = mockedDynamoDbClient.conditionalPut.mock.calls[0];
65
- expect(item.pk).toBe(`identity#${pixelId}#${identityId}`);
66
- expect(condition).toBe('attribute_not_exists(pk)');
67
- expect(values).toBeUndefined();
68
- });
69
- it('preserves caller identity metadata (cold: full write; warm: caller wins)', async () => {
70
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
71
- const cold = await IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, {
72
- identityId,
73
- traits: { emails: ['a@x.com'] },
74
- isPrimaryV2: true,
75
- version: '2',
76
- });
77
- expect(cold?.isPrimaryV2).toBe(true);
78
- expect(cold?.version).toBe('2');
79
- const stored = buildRecord({ emails: ['old@x.com'] }, 'T1');
80
- stored.response.isPrimaryV2 = false;
81
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(stored);
82
- const warm = await IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, {
83
- identityId,
84
- traits: { emails: ['new@x.com'] },
85
- isPrimaryV2: true,
86
- });
87
- expect(warm?.isPrimaryV2).toBe(true);
88
- expect(warm?.traits?.emails?.sort()).toEqual(['new@x.com', 'old@x.com']);
89
- });
90
- it('warm record: unions incoming with current and guards on the read updatedAt', async () => {
91
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(buildRecord({ emails: ['old@x.com'], phones: ['111'] }, 'T1'));
92
- const result = await IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, {
93
- identityId,
94
- traits: { emails: ['new@x.com'] },
95
- });
96
- expect(result?.traits?.emails?.sort()).toEqual(['new@x.com', 'old@x.com']);
97
- expect(result?.traits?.phones).toEqual(['111']);
98
- const [, , condition, values] = mockedDynamoDbClient.conditionalPut.mock.calls[0];
99
- expect(condition).toBe('updatedAt = :expectedUpdatedAt');
100
- expect(values).toEqual({ ':expectedUpdatedAt': 'T1' });
101
- });
102
- it('also refreshes the email pointer records', async () => {
103
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
104
- await IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, { identityId, traits: { emails: ['p@x.com'] } });
105
- expect(mockedDynamoDbClient.safeBatchWrite).toHaveBeenCalledTimes(1);
106
- const [, pointerItems] = mockedDynamoDbClient.safeBatchWrite.mock.calls[0];
107
- expect(pointerItems[0].pk).toBe(`email#${pixelId}#p@x.com`);
108
- });
109
- it('is order-independent: (A then B) equals (B then A)', async () => {
110
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
111
- const a = await IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, { identityId, traits: { emails: ['a@x.com'] } });
112
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(buildRecord((a?.traits ?? {}), 'T1'));
113
- const ab = await IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, { identityId, traits: { emails: ['b@x.com'] } });
114
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
115
- const b = await IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, { identityId, traits: { emails: ['b@x.com'] } });
116
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(buildRecord((b?.traits ?? {}), 'T1'));
117
- const ba = await IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, { identityId, traits: { emails: ['a@x.com'] } });
118
- expect(ab?.traits?.emails?.sort()).toEqual(ba?.traits?.emails?.sort());
119
- expect(ab?.traits?.emails?.sort()).toEqual(['a@x.com', 'b@x.com']);
120
- });
121
- it('retries on a write conflict then succeeds', async () => {
122
- mockedDynamoDbClient.safeGet
123
- .mockResolvedValueOnce(buildRecord({ emails: ['old@x.com'] }, 'T1'))
124
- .mockResolvedValueOnce(buildRecord({ emails: ['old@x.com'], other: ['raced'] }, 'T2'));
125
- mockedDynamoDbClient.conditionalPut
126
- .mockResolvedValueOnce({ success: false, conditionFailed: true })
127
- .mockResolvedValueOnce({ success: true, conditionFailed: false });
128
- const result = await IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, {
129
- identityId,
130
- traits: { emails: ['new@x.com'] },
131
- });
132
- expect(mockedDynamoDbClient.conditionalPut).toHaveBeenCalledTimes(2);
133
- expect(result?.traits?.emails?.sort()).toEqual(['new@x.com', 'old@x.com']);
134
- expect(mockedDynamoDbClient.conditionalPut.mock.calls[1][3]).toEqual({ ':expectedUpdatedAt': 'T2' });
135
- });
136
- it('returns undefined after exhausting retries on persistent conflict', async () => {
137
- mockedDynamoDbClient.safeGet.mockResolvedValue(buildRecord({ emails: ['old@x.com'] }, 'T1'));
138
- mockedDynamoDbClient.conditionalPut.mockResolvedValue({ success: false, conditionFailed: true });
139
- const result = await IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, {
140
- identityId,
141
- traits: { emails: ['new@x.com'] },
142
- });
143
- expect(result).toBeUndefined();
144
- expect(mockedDynamoDbClient.conditionalPut).toHaveBeenCalledTimes(3);
145
- });
146
- it('stops immediately (no retry) on a hard write error', async () => {
147
- mockedDynamoDbClient.safeGet.mockResolvedValueOnce(null);
148
- mockedDynamoDbClient.conditionalPut.mockResolvedValueOnce({ success: false, conditionFailed: false });
149
- const result = await IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, {
150
- identityId,
151
- traits: { emails: ['new@x.com'] },
152
- });
153
- expect(result).toBeUndefined();
154
- expect(mockedDynamoDbClient.conditionalPut).toHaveBeenCalledTimes(1);
155
- });
156
- it('returns undefined when params are missing', async () => {
157
- expect(await IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache('', { identityId, traits: {} })).toBeUndefined();
158
- expect(await IdentityCacheDynamoDbDbService.mergeTraitsIntoIdentityCache(pixelId, { identityId: '', traits: {} })).toBeUndefined();
159
- expect(mockedDynamoDbClient.conditionalPut).not.toHaveBeenCalled();
160
- });
161
- });
162
- describe('updateIdentityCache (regression via shared item-builder)', () => {
163
- it('batch-writes the identity# record plus one email pointer', async () => {
164
- const response = { identityId, traits: { emails: ['a@x.com'] } };
165
- await IdentityCacheDynamoDbDbService.updateIdentityCache(pixelId, response);
166
- const [, items] = mockedDynamoDbClient.safeBatchWrite.mock.calls[0];
167
- expect(items).toHaveLength(2);
168
- expect(items[0].pk).toBe(`identity#${pixelId}#${identityId}`);
169
- expect(items[0].response).toEqual(response);
170
- expect(items[1].pk).toBe(`email#${pixelId}#a@x.com`);
171
- });
172
- });
173
- //# sourceMappingURL=identity-traits-merge-write.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"identity-traits-merge-write.spec.js","sourceRoot":"","sources":["../../../../src/__tests__/identity-cache/identity-traits-merge-write.spec.ts"],"names":[],"mappings":"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"}