Skip to content

Commit

Permalink
Merge pull request #165 from jmartin4563/add-unit-test-coverage
Browse files Browse the repository at this point in the history
test: add unit test coverage to wrapper
  • Loading branch information
jmartin4563 authored Jun 30, 2023
2 parents c77d7ee + a435623 commit fc43845
Show file tree
Hide file tree
Showing 7 changed files with 283 additions and 1 deletion.
2 changes: 1 addition & 1 deletion nodejs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ function patchCommonJSHandler() {
return wrappedHandler.apply(this, args)
}

module.exports = {
module.exports = {
handler: process.env.NEW_RELIC_USE_ESM === 'true' ? patchESModuleHandler : patchCommonJSHandler,
getHandlerPath
}
129 changes: 129 additions & 0 deletions nodejs/test/unit/cjsErrorStates.tap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
'use strict'

const tap = require('tap')
const proxyquire = require('proxyquire').noCallThru().noPreserveCache()
const utils = require('@newrelic/test-utilities')
const path = require('node:path')

tap.test('CJS Edge Cases', (t) => {
t.autoend()
let handler
let helper
let originalEnv

t.beforeEach(() => {
originalEnv = { ...process.env }
process.env.NEW_RELIC_USE_ESM = 'false'

helper = utils.TestAgent.makeInstrumented()

const newrelic = helper.getAgentApi()

;({ handler } = proxyquire('../../index', {
'newrelic': newrelic
}))
})

t.afterEach(() => {
process.env = { ...originalEnv }
helper.unload()
})

t.test('should delete serverless mode env var if defined', (t) => {
process.env.LAMBDA_TASK_ROOT = './'
process.env.NEW_RELIC_SERVERLESS_MODE_ENABLED = 'true'

// redundant, but needed for this test
const newrelic = helper.getAgentApi()

;({ handler } = proxyquire('../../index', {
'newrelic': newrelic
}))

t.notOk(process.env.NEW_RELIC_SERVERLESS_MODE_ENABLED,
'NEW_RELIC_SERVERLESS_MODE_ENABLED env var should have been deleted')
t.end()
})

t.test('should throw when NEW_RELIC_LAMBDA_HANDLER is missing', (t) => {
t.throws(
() => handler({ key: 'this is a test'}, { functionName: 'testFn'}),
'No NEW_RELIC_LAMBDA_HANDLER environment variable set.',
)

t.end()
})

t.test('should throw when NEW_RELIC_LAMBDA_HANDLER is malformed', (t) => {
// Missing the .functionName part
process.env.NEW_RELIC_LAMBDA_HANDLER = 'test/unit/fixtures/cjs/handler'

t.throws(
() => handler({ key: 'this is a test'}, { functionName: 'testFn'}),
'Improperly formatted handler environment variable: test/unit/fixtures/cjs/handler',
)

t.end()
})

t.test('should throw when NEW_RELIC_LAMBDA_HANDLER module cannot be resolved', (t) => {
const handlerPath = 'test/unit/fixtures/cjs/'
const handlerFile = 'notFound'
const handlerMethod = 'noMethodFound'
const modulePath = path.resolve('./', handlerPath)
const extensions = ['.cjs', '.js']
process.env.NEW_RELIC_LAMBDA_HANDLER = `${handlerPath}${handlerFile}.${handlerMethod}`

t.throws(
() => handler({ key: 'this is a test'}, { functionName: handlerMethod }),
`Unable to resolve module file at ${modulePath} with the following extensions: ${extensions.join(',')}`
)

t.end()
})

t.test('should throw when NEW_RELIC_LAMBDA_HANDLER does not export provided function', (t) => {
const handlerPath = 'test/unit/fixtures/cjs/'
const handlerFile = 'errors'
const handlerMethod = 'noMethodFound'

process.env.NEW_RELIC_LAMBDA_HANDLER = `${handlerPath}${handlerFile}.${handlerMethod}`

t.throws(
() => handler({ key: 'this is a test'}, { functionName: handlerMethod }),
`Handler '${handlerMethod}' missing on module '${handlerPath}'`,
)

t.end()
})

t.test('should throw when NEW_RELIC_LAMBDA_HANDLER export is not a function', (t) => {
const handlerPath = 'test/unit/fixtures/cjs/'
const handlerFile = 'errors'
const handlerMethod = 'notAfunction'

process.env.NEW_RELIC_LAMBDA_HANDLER = `${handlerPath}${handlerFile}.${handlerMethod}`

t.throws(
() => handler({ key: 'this is a test'}, { functionName: handlerMethod }),
`Handler '${handlerMethod}' from 'test/unit/fixtures/cjs/errors' is not a function`,
)

t.end()
})

t.test('should throw when NEW_RELIC_LAMBDA_HANDLER throws on require', (t) => {
const handlerPath = 'test/unit/fixtures/cjs/'
const handlerFile = 'badRequire'
const handlerMethod = 'handler'

process.env.NEW_RELIC_LAMBDA_HANDLER = `${handlerPath}${handlerFile}.${handlerMethod}`

t.throws(
() => handler({ key: 'this is a test'}, { functionName: handlerMethod }),
`Unable to import module '${handlerPath}${handlerFile}'`,
)

t.end()
})
})
129 changes: 129 additions & 0 deletions nodejs/test/unit/esmErrorStates.tap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
'use strict'

const tap = require('tap')
const proxyquire = require('proxyquire').noCallThru().noPreserveCache()
const utils = require('@newrelic/test-utilities')
const path = require('node:path')

tap.test('ESM Edge Cases', (t) => {
t.autoend()
let handler
let helper
let originalEnv

t.beforeEach(() => {
originalEnv = { ...process.env }
process.env.NEW_RELIC_USE_ESM = 'true'

helper = utils.TestAgent.makeInstrumented()

const newrelic = helper.getAgentApi()

;({ handler } = proxyquire('../../index', {
'newrelic': newrelic
}))
})

t.afterEach(() => {
process.env = { ...originalEnv }
helper.unload()
})

t.test('should delete serverless mode env var if defined', async(t) => {
process.env.LAMBDA_TASK_ROOT = './'
process.env.NEW_RELIC_SERVERLESS_MODE_ENABLED = 'true'

// redundant, but needed for this test
const newrelic = helper.getAgentApi()

;({ handler } = proxyquire('../../index', {
'newrelic': newrelic
}))

t.notOk(process.env.NEW_RELIC_SERVERLESS_MODE_ENABLED,
'NEW_RELIC_SERVERLESS_MODE_ENABLED env var should have been deleted')
t.end()
})

t.test('should throw when NEW_RELIC_LAMBDA_HANDLER is missing', (t) => {
t.rejects(
() => handler({ key: 'this is a test'}, { functionName: 'testFn'}),
'No NEW_RELIC_LAMBDA_HANDLER environment variable set.',
)

t.end()
})

t.test('should throw when NEW_RELIC_LAMBDA_HANDLER is malformed', async(t) => {
// Missing the .functionName part
process.env.NEW_RELIC_LAMBDA_HANDLER = 'test/unit/fixtures/esm/handler'

t.rejects(
() => handler({ key: 'this is a test'}, { functionName: 'testFn'}),
'Improperly formatted handler environment variable: test/unit/fixtures/esm/handler',
)

t.end()
})

t.test('should throw when NEW_RELIC_LAMBDA_HANDLER module cannot be resolved', async(t) => {
const handlerPath = 'test/unit/fixtures/esm/'
const handlerFile = 'notFound'
const handlerMethod = 'noMethodFound'
const modulePath = path.resolve('./', handlerPath)
const extensions = ['.mjs', '.js']
process.env.NEW_RELIC_LAMBDA_HANDLER = `${handlerPath}${handlerFile}.${handlerMethod}`

t.rejects(
() => handler({ key: 'this is a test'}, { functionName: handlerMethod }),
`Unable to resolve module file at ${modulePath} with the following extensions: ${extensions.join(',')}`
)

t.end()
})

t.test('should throw when NEW_RELIC_LAMBDA_HANDLER does not export provided function', async(t) => {
const handlerPath = 'test/unit/fixtures/esm/'
const handlerFile = 'errors'
const handlerMethod = 'noMethodFound'

process.env.NEW_RELIC_LAMBDA_HANDLER = `${handlerPath}${handlerFile}.${handlerMethod}`

t.rejects(
() => handler({ key: 'this is a test'}, { functionName: handlerMethod }),
`Handler '${handlerMethod}' missing on module '${handlerPath}'`,
)

t.end()
})

t.test('should throw when NEW_RELIC_LAMBDA_HANDLER export is not a function', async(t) => {
const handlerPath = 'test/unit/fixtures/esm/'
const handlerFile = 'errors'
const handlerMethod = 'notAfunction'

process.env.NEW_RELIC_LAMBDA_HANDLER = `${handlerPath}${handlerFile}.${handlerMethod}`

t.rejects(
() => handler({ key: 'this is a test'}, { functionName: handlerMethod }),
`Handler '${handlerMethod}' from 'test/unit/fixtures/esm/errors' is not a function`,
)

t.end()
})

t.test('should throw when NEW_RELIC_LAMBDA_HANDLER throws on import', async(t) => {
const handlerPath = 'test/unit/fixtures/esm/'
const handlerFile = 'badImport'
const handlerMethod = 'handler'

process.env.NEW_RELIC_LAMBDA_HANDLER = `${handlerPath}${handlerFile}.${handlerMethod}`

t.rejects(
() => handler({ key: 'this is a test'}, { functionName: handlerMethod }),
`Unable to import module '${handlerPath}${handlerFile}'`,
)

t.end()
})
})
11 changes: 11 additions & 0 deletions nodejs/test/unit/fixtures/cjs/badRequire.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
'use strict'

// eslint-disable-next-line no-unused-vars
const notFoundDependency = require('path/not/found')

exports.handler = (event) => {
return {
statusCode: 200,
body: JSON.stringify(event)
}
}
3 changes: 3 additions & 0 deletions nodejs/test/unit/fixtures/cjs/errors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
'use strict'

exports.notAfunction = `This is a string.`
9 changes: 9 additions & 0 deletions nodejs/test/unit/fixtures/esm/badImport.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable-next-line no-unused-vars
import notFoundDependency from 'path/not/found'

export function handler(event) {
return {
statusCode: 200,
body: JSON.stringify(event)
}
}
1 change: 1 addition & 0 deletions nodejs/test/unit/fixtures/esm/errors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const notAfunction = `This is a string.`

0 comments on commit fc43845

Please sign in to comment.