Skip to content

Commit

Permalink
EDSC-4265: Adds tests for generateNote
Browse files Browse the repository at this point in the history
  • Loading branch information
dmistry1 committed Nov 21, 2024
1 parent 37278d4 commit f4a4f17
Show file tree
Hide file tree
Showing 7 changed files with 292 additions and 31 deletions.
1 change: 1 addition & 0 deletions serverless-configs/aws-functions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
#
generateNotebook:
handler: serverless/src/generateNotebook/handler.default
timeout: ${env:LAMBDA_TIMEOUT, '30'}
events:
- http:
method: post
Expand Down
4 changes: 2 additions & 2 deletions serverless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,8 @@ custom:
external: ['knex', 'pg', 'sharp']
bundle: true
minify: ${self:custom.minifyBuild.${self:provider.stage}}
# watch:
# ignore: ['.esbuild', 'dist', 'node_modules', '.build', 'static', '*.test.js']
watch:
ignore: ['.esbuild', 'dist', 'node_modules', '.build', 'static', '*.test.js']

# Manage resource count (Maximum of 200) by splitting up the cloudformation templates
splitStacks:
Expand Down
246 changes: 246 additions & 0 deletions serverless/src/generateNotebook/__tests__/handler.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
import nock from 'nock'

import * as getEarthdataConfig from '../../../../sharedUtils/config'

import * as getAccessTokenFromJwtToken from '../../util/urs/getAccessTokenFromJwtToken'
import * as getJwtToken from '../../util/getJwtToken'
import * as getS3Client from '../../../../static/src/js/util/getS3Client'
import generateNotebook from '../handler'

const OLD_ENV = process.env

jest.mock('@aws-sdk/s3-request-presigner', () => ({
getSignedUrl: jest.fn().mockResolvedValue('https://mock-signed-url.com')
}))

const mockS3Send = jest.fn()
const mockS3Client = { send: mockS3Send }

beforeEach(() => {
jest.spyOn(getJwtToken, 'getJwtToken').mockImplementation(() => 'mockJwt')
jest.spyOn(getAccessTokenFromJwtToken, 'getAccessTokenFromJwtToken').mockImplementation(() => ({ access_token: 'mockAccessToken' }))

jest.spyOn(getEarthdataConfig, 'getEarthdataConfig').mockImplementationOnce(() => ({
graphQlHost: 'http://graphql.example.com'
}))

mockS3Send.mockResolvedValue({ $metadata: { httpStatusCode: 200 } })
jest.spyOn(getS3Client, 'getS3Client').mockReturnValue(mockS3Client)

process.env = { ...OLD_ENV }
delete process.env.NODE_ENV

process.env.GENERATE_NOTEBOOKS_BUCKET_NAME = 'MOCK_GENERATE_NOTEBOOK_BUCKET'
})

afterEach(() => {
jest.clearAllMocks()
mockS3Send.mockReset()
})

describe('generateNotebook', () => {
describe('when successfully generates a notebook', () => {
test('returns a signed URL', async () => {
nock(/graphql/)
.post('/api')
.reply(200, {
data: {
granules: {
items: [{
conceptId: 'G1234-MOCK',
title: 'Mock Granule',
collection: {
conceptId: 'C1234-MOCK',
title: 'Mock Collection',
variables: {
items: [{
name: 'Mock Variable'
}]
}
}
}]
}
}
})

const event = {
body: JSON.stringify({
boundingBox: '-180, -90, 180, 90',
referrerUrl: 'http://example.com',
granuleId: 'G1234-MOCK',
variableId: 'V1234-MOCK'
}),
headers: {}
}

const response = await generateNotebook(event)

expect(response.statusCode).toBe(307)
expect(response.headers).toHaveProperty('Location')
expect(response.headers.Location).toBe('https://mock-signed-url.com')
})
})

describe('when saving to S3 fails', () => {
test('throws an error when failing to save notebook to S3', async () => {
nock(/graphql/)
.post('/api')
.reply(200, {
data: {
granules: {
items: [{
conceptId: 'G1234-MOCK',
title: 'Mock Granule',
collection: {
conceptId: 'C1234-MOCK',
title: 'Mock Collection',
variables: {
items: [{
name: 'Mock Variable'
}]
}
}
}]
}
}
})

mockS3Send.mockResolvedValue({ $metadata: { httpStatusCode: 500 } })
jest.spyOn(getS3Client, 'getS3Client').mockReturnValue(mockS3Client)

const event = {
body: JSON.stringify({
boundingBox: '-180, -90, 180, 90',
referrerUrl: 'http://example.com',
granuleId: 'G1234-MOCK',
variableId: 'V1234-MOCK'
}),
headers: {}
}

const response = await generateNotebook(event)

expect(response.statusCode).toBe(500)
expect(JSON.parse(response.body)).toHaveProperty('errors')
expect(JSON.parse(response.body).errors[0]).toBe('Error: Failed to save notebook to S3')
})
})

describe('when bounding field are is provided', () => {
test('generates notebook without bounding box field', async () => {
nock(/graphql/)
.post('/api')
.reply(200, {
data: {
granules: {
items: [{
conceptId: 'G1234-MOCK',
title: 'Mock Granule',
collection: {
conceptId: 'C1234-MOCK',
title: 'Mock Collection',
variables: {
items: [{
name: 'Mock Variable'
}]
}
}
}]
}
}
})

const event = {
body: JSON.stringify({
granuleId: 'G1234-MOCK',
variableId: 'V1234-MOCK'
}),
headers: {}
}

await generateNotebook(event)

// Check that the notebook was generated without bounding box values
expect(mockS3Send).toHaveBeenCalled()
const s3PutCall = mockS3Send.mock.calls[0][0]
const notebookContent = JSON.parse(s3PutCall.input.Body)
expect(notebookContent).toHaveProperty('cells')
expect(notebookContent.cells.every((cell) => !(cell.source && cell.source.includes('"minLon"')))).toBeTruthy()
})
})

describe('when JWT token is not present', () => {
test('returns a singed URL', async () => {
nock(/graphql/)
.post('/api')
.reply(200, {
data: {
granules: {
items: [{
conceptId: 'G1234-MOCK',
title: 'Mock Granule',
collection: {
conceptId: 'C1234-MOCK',
title: 'Mock Collection',
variables: {
items: [{
name: 'Mock Variable'
}]
}
}
}]
}
}
})

jest.spyOn(getJwtToken, 'getJwtToken').mockReturnValue(null)

const event = {
body: JSON.stringify({
granuleId: 'G1234-MOCK',
variableId: 'V1234-MOCK'
}),
headers: { 'mock-header': 'mock-value' }
}

const response = await generateNotebook(event)

expect(response.statusCode).toBe(307)
expect(response.headers).toHaveProperty('Location')
expect(response.headers.Location).toBe('https://mock-signed-url.com')
})
})

describe('when call to graphql results in 500', () => {
test('returns an error', async () => {
nock(/graphql/)
.post(/api/)
.reply(500, {
errors: [
'Test error message'
]
})

mockS3Send.mockReset()

const event = {
body: JSON.stringify({
granuleId: 'G1234-MOCK',
variableId: 'V1234-MOCK'
}),
headers: {}
}

const response = await generateNotebook(event)

expect(response.statusCode).toEqual(500)

const { body } = response
const parsedBody = JSON.parse(body)
const { errors } = parsedBody
const [errorMessage] = errors

expect(errorMessage).toEqual('Test error message')
})
})
})
Loading

0 comments on commit f4a4f17

Please sign in to comment.