@mbc-cqrs-serverless/core
Version:
CQRS and event base core
320 lines • 10.7 kB
JavaScript
;
/**
* Test Data Builders
*
* Provides factory functions for creating test data used across
* integration tests. This eliminates repetitive data creation and
* ensures consistent test fixtures.
*
* Usage:
* import {
* createTestItem,
* createTestItems,
* createBatchWriteRequest
* } from './utilities/test-data-builders'
*
* const item = createTestItem({ pk: 'user-1', sk: 'profile' })
* const items = createTestItems(100)
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.unmarshall = exports.marshall = exports.DYNAMODB_BATCH_SIZE = void 0;
exports.createTestItem = createTestItem;
exports.createTestItems = createTestItems;
exports.createMarshalledItem = createMarshalledItem;
exports.createMarshalledItems = createMarshalledItems;
exports.createKey = createKey;
exports.createKeys = createKeys;
exports.createBatchWriteRequest = createBatchWriteRequest;
exports.createBatchGetRequest = createBatchGetRequest;
exports.splitIntoBatches = splitIntoBatches;
exports.createS3Content = createS3Content;
exports.createS3Metadata = createS3Metadata;
exports.createSQSMessageBody = createSQSMessageBody;
exports.createSQSBatchEntries = createSQSBatchEntries;
exports.createSNSMessage = createSNSMessage;
exports.createSFNInput = createSFNInput;
exports.createSFNExecutionName = createSFNExecutionName;
exports.createRandomString = createRandomString;
exports.createNestedTestData = createNestedTestData;
exports.createMixedTypeTestData = createMixedTypeTestData;
exports.createLargeTestData = createLargeTestData;
exports.unmarshallItem = unmarshallItem;
exports.unmarshallItems = unmarshallItems;
const util_dynamodb_1 = require("@aws-sdk/util-dynamodb");
/**
* Creates a single test item
*/
function createTestItem(options = {}) {
const { pk = `pk-${Date.now()}-${Math.random().toString(36).substring(7)}`, sk = `sk-${Date.now()}-${Math.random().toString(36).substring(7)}`, data = {}, withTimestamp = false, withVersion, } = options;
const item = {
pk,
sk,
...data,
};
if (withTimestamp) {
item.createdAt = new Date().toISOString();
item.updatedAt = new Date().toISOString();
}
if (withVersion !== undefined) {
item.version = withVersion;
}
return item;
}
/**
* Creates multiple test items with sequential IDs
*/
function createTestItems(count, options = {}) {
const { pkPrefix = 'pk', skPrefix = 'sk', dataGenerator = () => ({}), withTimestamp = false, withVersion = false, } = options;
return Array.from({ length: count }, (_, i) => createTestItem({
pk: `${pkPrefix}-${i}`,
sk: `${skPrefix}-${i}`,
data: dataGenerator(i),
withTimestamp,
withVersion: withVersion ? 1 : undefined,
}));
}
/**
* Creates a marshalled DynamoDB item
*/
function createMarshalledItem(options = {}) {
const item = createTestItem(options);
return (0, util_dynamodb_1.marshall)(item);
}
/**
* Creates multiple marshalled DynamoDB items
*/
function createMarshalledItems(count, options = {}) {
return createTestItems(count, options).map((item) => (0, util_dynamodb_1.marshall)(item));
}
// ============================================================================
// DynamoDB Key Builders
// ============================================================================
/**
* Creates a DynamoDB key object
*/
function createKey(pk, sk) {
return (0, util_dynamodb_1.marshall)({ pk, sk });
}
/**
* Creates multiple DynamoDB keys
*/
function createKeys(items) {
return items.map(({ pk, sk }) => createKey(pk, sk));
}
// ============================================================================
// Batch Operation Builders
// ============================================================================
/**
* DynamoDB batch size limit
*/
exports.DYNAMODB_BATCH_SIZE = 25;
/**
* Creates a BatchWriteItem request structure for DynamoDB
*/
function createBatchWriteRequest(tableName, items) {
return {
RequestItems: {
[tableName]: items.map((item) => ({
PutRequest: { Item: (0, util_dynamodb_1.marshall)(item) },
})),
},
};
}
/**
* Creates a BatchGetItem request structure for DynamoDB
*/
function createBatchGetRequest(tableName, keys) {
return {
RequestItems: {
[tableName]: {
Keys: createKeys(keys),
},
},
};
}
/**
* Splits items into batches of the specified size
*/
function splitIntoBatches(items, batchSize = exports.DYNAMODB_BATCH_SIZE) {
const batches = [];
for (let i = 0; i < items.length; i += batchSize) {
batches.push(items.slice(i, i + batchSize));
}
return batches;
}
// ============================================================================
// S3 Object Builders
// ============================================================================
/**
* Creates test content for S3 objects
*/
function createS3Content(options = {}) {
const { type = 'text', size = 1024, data } = options;
switch (type) {
case 'json':
return Buffer.from(JSON.stringify(data || { test: true, timestamp: Date.now() }));
case 'binary':
return Buffer.alloc(size, 0xff);
case 'text':
default:
return Buffer.from('x'.repeat(size));
}
}
/**
* Creates S3 object metadata
*/
function createS3Metadata(options = {}) {
const { contentType = 'application/octet-stream', customMetadata } = options;
return {
ContentType: contentType,
...(customMetadata && { Metadata: customMetadata }),
};
}
// ============================================================================
// SQS Message Builders
// ============================================================================
/**
* Creates an SQS message body
*/
function createSQSMessageBody(data) {
return JSON.stringify(data);
}
/**
* Creates multiple SQS message entries for batch operations
*/
function createSQSBatchEntries(messages) {
return messages.map(({ id, body, delaySeconds, messageAttributes }) => ({
Id: id,
MessageBody: JSON.stringify(body),
...(delaySeconds !== undefined && { DelaySeconds: delaySeconds }),
...(messageAttributes && { MessageAttributes: messageAttributes }),
}));
}
// ============================================================================
// SNS Message Builders
// ============================================================================
/**
* Creates an SNS message for publishing
*/
function createSNSMessage(options) {
const { subject, message, messageAttributes } = options;
return {
...(subject && { Subject: subject }),
Message: typeof message === 'string' ? message : JSON.stringify(message),
...(messageAttributes && { MessageAttributes: messageAttributes }),
};
}
// ============================================================================
// Step Functions Input Builders
// ============================================================================
/**
* Creates Step Functions execution input
*/
function createSFNInput(data) {
return JSON.stringify(data);
}
/**
* Creates a Step Functions execution name
*/
function createSFNExecutionName(prefix = 'test-execution') {
return `${prefix}-${Date.now()}-${Math.random().toString(36).substring(7)}`;
}
// ============================================================================
// Generic Test Data Generators
// ============================================================================
/**
* Creates a random string of specified length
*/
function createRandomString(length) {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
for (let i = 0; i < length; i++) {
result += chars.charAt(Math.floor(Math.random() * chars.length));
}
return result;
}
/**
* Creates test data with nested structures
*/
function createNestedTestData(depth, breadth = 3) {
if (depth <= 0) {
return { value: createRandomString(10) };
}
const result = {};
for (let i = 0; i < breadth; i++) {
result[`level_${depth}_item_${i}`] = createNestedTestData(depth - 1, breadth);
}
return result;
}
/**
* Creates test data with various JavaScript types
*/
function createMixedTypeTestData() {
return {
stringValue: 'test string',
numberValue: 42,
floatValue: 3.14159,
booleanTrue: true,
booleanFalse: false,
nullValue: null,
arrayValue: [1, 2, 3, 'four', { five: 5 }],
objectValue: {
nested: {
deep: {
value: 'deep value',
},
},
},
dateString: new Date().toISOString(),
emptyString: '',
emptyArray: [],
emptyObject: {},
largeNumber: Number.MAX_SAFE_INTEGER,
negativeNumber: -999,
zeroValue: 0,
};
}
/**
* Creates large test data for performance/memory tests
*/
function createLargeTestData(options = {}) {
const { itemCount = 1000, stringLength = 100, includeNested = false, } = options;
const items = Array.from({ length: itemCount }, (_, i) => ({
id: i,
name: `item-${i}`,
data: createRandomString(stringLength),
...(includeNested && { nested: createNestedTestData(2, 2) }),
}));
return {
items,
metadata: {
totalCount: itemCount,
generatedAt: new Date().toISOString(),
},
};
}
// ============================================================================
// Unmarshall Utilities
// ============================================================================
/**
* Unmarshalls a DynamoDB item to a plain JavaScript object
*/
function unmarshallItem(item) {
return (0, util_dynamodb_1.unmarshall)(item);
}
/**
* Unmarshalls multiple DynamoDB items
*/
function unmarshallItems(items) {
return items.map((item) => unmarshallItem(item));
}
// ============================================================================
// Index File Export
// ============================================================================
/**
* Re-export for convenience
*/
var util_dynamodb_2 = require("@aws-sdk/util-dynamodb");
Object.defineProperty(exports, "marshall", { enumerable: true, get: function () { return util_dynamodb_2.marshall; } });
Object.defineProperty(exports, "unmarshall", { enumerable: true, get: function () { return util_dynamodb_2.unmarshall; } });
//# sourceMappingURL=test-data-builders.js.map