Looking for a solution without using any libraries (as they haven't worked in my case). How can I make it work for that promise returned by the dynamodb query?
Check out the code to be tested below:
const isUrl = require('is-url');
const AWS = require('aws-sdk');
const { nanoid } = require('nanoid/async');
const express = require('express');
const router = express.Router();
const dynamoDb = new AWS.DynamoDB.DocumentClient();
// URL from users
router.post('/', async (req, res) => {
// urlId contains converted short url characters generated by nanoid
const urlId = await nanoid(8);
const { longUrl } = req.body;
// Veryfying url Format using isUrl, this return a boolean
const checkUrl = isUrl(longUrl);
if (checkUrl === false) {
return res.status(400).json({ error: 'Invalid URL, please try again!!!' });
}
const originalUrl = longUrl;
const userType = 'anonymous'; // user type for anonymous users
const tableName = 'table-name'; // table name for storing url's
const anonymousUrlCheckParams = {
TableName: tableName,
Key: {
userId: userType,
originalUrl,
},
};
const paramsForTransaction = {
TransactItems: [
{
Put: {
TableName: tableName,
Item: {
userId: userType,
originalUrl,
convertedUrl: `https://url/${urlId}`,
},
},
},
{
Put: {
TableName: tableName,
Item: {
userId: urlId,
originalUrl,
},
ConditionExpression: 'attribute_not_exists(userId)',
},
},
],
};
try {
const dynamoDbGetResults = await dynamoDb
.get(anonymousUrlCheckParams)
.promise();
if (
Object.keys(dynamoDbGetResults).length === 0 &&
dynamoDbGetResults.constructor === Object
) {
await dynamoDb.transactWrite(paramsForTransaction).promise();
return res.status(201).json({
convertedUrl: `https://trimify.awssensei.tk/${urlId}`,
});
}
return res.status(201).json({
convertedUrl: dynamoDbGetResults.Item.convertedUrl,
});
} catch (err) {
return res
.status(500)
.json({ error: 'Unknown Server Error, Please Trimify Again!' });
}
});
module.exports = router;
And here's the test code:
describe('Test for Authenticated Url', () => {
beforeEach(() => {
jest.resetModules();
});
test('should return converted url for authenticated user', async () => {
const mockedDocumentClient = {
get: jest.fn(),
transactWrite: jest.fn(),
};
const mockedDynamoDB = {
DocumentClient: jest.fn(() => mockedDocumentClient),
};
jest.doMock('aws-sdk', () => ({ DynamoDB: mockedDynamoDB }));
mockedDocumentClient.get.mockImplementation((params, callback) => {
const data = {
Item: {
convertedUrl: 'xyz',
},
};
callback(null, data);
});
mockedDocumentClient.transactWrite.mockImplementation(
(params, callback) => {
callback(null);
}
);
const app = require('../app');
const response = await request(app).post('/auth-ops/convert').send({
longUrl: 'https://google.com',
userId: 'google-oauth2|110198332436292901252',
});
expect(response.body).toMatchObject({ convertedUrl: 'xyz' });
expect(response.statusCode).toBe(201);
});
test('should send 201 when it is new Url', async () => {
const mockedDocumentClient = {
get: jest.fn(),
transactWrite: jest.fn(),
};
const mockedDynamoDB = {
DocumentClient: jest.fn(() => mockedDocumentClient),
};
jest.doMock('aws-sdk', () => ({ DynamoDB: mockedDynamoDB }));
mockedDocumentClient.get.mockImplementation((params, callback) => {
const data = {};
callback(null, data);
});
mockedDocumentClient.transactWrite.mockImplementation(
(params, callback) => {
callback(null);
}
);
const app = require('../app');
const response = await request(app).post('/auth-ops/convert').send({
longUrl: 'https://google.com',
userId: 'google-oauth2|110198332436292901252',
});
expect(response.body).not.toBe(undefined);
expect(response.statusCode).toBe(201);
});
});