Skip to content

Commit

Permalink
Merge pull request #82 from shiftcode/#80-enhance-tests
Browse files Browse the repository at this point in the history
#80 enhance tests
  • Loading branch information
michaelwittwer authored Nov 30, 2018
2 parents 85f098d + e18c4a4 commit 24017b9
Show file tree
Hide file tree
Showing 22 changed files with 1,183 additions and 82 deletions.
31 changes: 31 additions & 0 deletions src/config/update-config.function.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// tslint:disable:no-empty

import { DateToNumberMapper } from '../mapper/custom'
import { dynamoEasyConfig } from './dynamo-easy-config'
import { updateDynamoEasyConfig } from './update-config.function'

describe('updateDynamoEasyConfig', () => {

it('should throw when providing invalid stuff', () => {
expect(() => updateDynamoEasyConfig({ logReceiver: <any>null })).toThrow()
expect(() => updateDynamoEasyConfig({ dateMapper: <any>null })).toThrow()
})

it('should have defaults', () => {
expect(dynamoEasyConfig.logReceiver).toBeDefined()
expect(dynamoEasyConfig.dateMapper).toBeDefined()
})

it('should work when providing valid stuff', () => {
const myLogReceiver = () => {}
const myDateMapper = { ...DateToNumberMapper }
updateDynamoEasyConfig({
logReceiver: myLogReceiver,
dateMapper: myDateMapper,
})
expect(dynamoEasyConfig.logReceiver).toBe(myLogReceiver)
expect(dynamoEasyConfig.dateMapper).toBe(myDateMapper)

})

})
3 changes: 3 additions & 0 deletions src/config/update-config.function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@ export function updateDynamoEasyConfig(config: Partial<Config>): void {
if (config.logReceiver !== undefined && typeof config.logReceiver !== 'function') {
throw new Error('Config.logReceiver has to be a function')
}
if (config.dateMapper !== undefined && (config.dateMapper === null || typeof config.dateMapper.toDb !== 'function' || typeof config.dateMapper.fromDb !== 'function')) {
throw new Error('Config.dateMapper must be an object of type MapperForType')
}
Object.assign(dynamoEasyConfig, config)
}
85 changes: 85 additions & 0 deletions src/decorator/metadata/metadata.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// tslint:disable:no-non-null-assertion
import {
ModelWithABunchOfIndexes, ModelWithAutogeneratedId,
ModelWithGSI,
ModelWithLSI,
SimpleWithCompositePartitionKeyModel,
SimpleWithPartitionKeyModel,
} from '../../../test/models'
import { INDEX_ACTIVE, INDEX_ACTIVE_CREATED_AT, INDEX_COUNT } from '../../../test/models/model-with-indexes.model'
import { Metadata } from './metadata'

describe('metadata', () => {
let metaDataPartitionKey: Metadata<SimpleWithPartitionKeyModel>
let metaDataComposite: Metadata<SimpleWithCompositePartitionKeyModel>
let metaDataLsi: Metadata<ModelWithLSI>
let metaDataGsi: Metadata<ModelWithGSI>
let metaDataIndexes: Metadata<ModelWithABunchOfIndexes>
let metaDataUuid: Metadata<ModelWithAutogeneratedId>

beforeEach(() => {
metaDataPartitionKey = new Metadata(SimpleWithPartitionKeyModel)
metaDataComposite = new Metadata(SimpleWithCompositePartitionKeyModel)
metaDataLsi = new Metadata(ModelWithLSI)
metaDataGsi = new Metadata(ModelWithGSI)
metaDataIndexes = new Metadata(ModelWithABunchOfIndexes)
metaDataUuid = new Metadata(ModelWithAutogeneratedId)
})

it('forProperty', () => {
const forId = metaDataPartitionKey.forProperty('id')
expect(forId).toBeDefined()
expect(forId!.key).toBeDefined()
expect(forId!.name).toBe('id')
expect(forId!.typeInfo).toBeDefined()
expect(forId!.typeInfo!.isCustom).toBeFalsy()
})

it('getKeysWithUUID', () => {
const uuid = metaDataUuid.getKeysWithUUID()
expect(uuid.length).toBe(1)
expect(uuid[0].key).toBeDefined()
expect(uuid[0].key!.uuid).toBeTruthy()
expect(uuid[0].name).toBe('id')

})

it('getPartitionKey', () => {
expect(metaDataPartitionKey.getPartitionKey()).toEqual('id')
expect(metaDataGsi.getPartitionKey(INDEX_ACTIVE)).toEqual('active')
expect(metaDataIndexes.getPartitionKey(INDEX_COUNT)).toEqual('myId')
expect(metaDataIndexes.getPartitionKey(INDEX_ACTIVE_CREATED_AT)).toEqual('active')

})

it('getSortKey', () => {
expect(metaDataPartitionKey.getSortKey()).toBe(null)
expect(metaDataComposite.getSortKey()).toBe('creationDate')
expect(metaDataLsi.getSortKey(INDEX_ACTIVE)).toBe('active')
expect(() => metaDataGsi.getSortKey(INDEX_ACTIVE)).toThrow()
expect(metaDataIndexes.getSortKey(INDEX_ACTIVE_CREATED_AT)).toBe('createdAt')
})

it('getIndexes', () => {
expect(metaDataLsi.getIndexes()).toEqual([
{ partitionKey: 'id', sortKey: 'active' },
])
expect(metaDataGsi.getIndexes()).toEqual([
{ partitionKey: 'active' },
])
expect(metaDataIndexes.getIndexes()).toEqual([
{ partitionKey: 'active', sortKey: 'createdAt' },
{ partitionKey: 'myId', sortKey: 'count' },
])
})

it('getIndex', () => {
expect(metaDataPartitionKey.getIndexes().length).toBe(0)
expect(metaDataPartitionKey.getIndex('blub')).toBe(null)
expect(metaDataIndexes.getIndex(INDEX_ACTIVE_CREATED_AT)).toEqual({
partitionKey: 'active',
sortKey: 'createdAt',
})
})

})
96 changes: 85 additions & 11 deletions src/dynamo/batchget/batch-get.request.spec.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,97 @@
import * as DynamoDB from 'aws-sdk/clients/dynamodb'
import { of } from 'rxjs'
import { getTableName } from '../../../test/helper'
import { SimpleWithCompositePartitionKeyModel, SimpleWithPartitionKeyModel } from '../../../test/models'
import { Organization } from '../../../test/models/organization.model'
import { Attributes } from '../../mapper'
import { DynamoRx } from '../dynamo-rx'
import { BatchGetRequest } from './batch-get.request'

describe('batch get', () => {
let request: BatchGetRequest

beforeEach(() => {
request = new BatchGetRequest()

describe('params', () => {

beforeEach(() => request = new BatchGetRequest())

it('base params', () => {
const params = request.params
expect(params).toEqual({ RequestItems: {} })
})

it('key', () => {
request.forModel(Organization, ['idValue'])
const params = request.params
expect(params.RequestItems).toBeDefined()
expect(params.RequestItems.Organization).toBeDefined()
expect(params.RequestItems.Organization).toEqual({ Keys: [{ id: { S: 'idValue' } }] })
})
})

it('base params', () => {
const params = request.params
expect(params).toEqual({ RequestItems: {} })

describe('forModel', () => {
beforeEach(() => request = new BatchGetRequest())

it('should throw when same table is used 2 times', () => {
request.forModel(SimpleWithPartitionKeyModel, ['idVal'])
expect(() => request.forModel(SimpleWithPartitionKeyModel, ['otherVal'])).toThrow()
})

it('should throw when providing null value ', () => {
expect(() => request.forModel(SimpleWithPartitionKeyModel, [<any>null])).toThrow()
})

it('should throw when sortKey is missing', () => {
expect(() => request.forModel(SimpleWithCompositePartitionKeyModel, [{ partitionKey: 'idVal' }]))
})

it('should throw when partitionKey is neither string nor object', () => {
expect(() => request.forModel(SimpleWithCompositePartitionKeyModel, [<any>78]))
expect(() => request.forModel(SimpleWithCompositePartitionKeyModel, [<any>true]))
expect(() => request.forModel(SimpleWithCompositePartitionKeyModel, [<any>new Date()]))
})

})

it('key', () => {
request.forModel(Organization, ['idValue'])
const params = request.params
expect(params.RequestItems).toBeDefined()
expect(params.RequestItems.Organization).toBeDefined()
expect(params.RequestItems.Organization).toEqual({ Keys: [{ id: { S: 'idValue' } }] })

describe('should map the result items', () => {
let batchGetItemsSpy: jasmine.Spy
const jsItem: SimpleWithPartitionKeyModel = { id: 'idVal', age: 20 }
const dbItem: Attributes<SimpleWithPartitionKeyModel> = {
id: { S: 'idVal' },
age: { N: '20' },
}
const sampleResponse: DynamoDB.BatchGetItemOutput = {
Responses: {
[getTableName(SimpleWithPartitionKeyModel)]: [dbItem],
},
UnprocessedKeys: {},
}

beforeEach(() => {
batchGetItemsSpy = jasmine.createSpy().and.returnValue(of(sampleResponse))
const dynamoRx: DynamoRx = <any>{ batchGetItems: batchGetItemsSpy }
request = new BatchGetRequest()
Object.assign(request, { dynamoRx })
request.forModel(SimpleWithPartitionKeyModel, ['idVal'])
})

it('exec', async () => {
const result = await request.exec().toPromise()
expect(batchGetItemsSpy).toHaveBeenCalled()
expect(result).toEqual({ [getTableName(SimpleWithPartitionKeyModel)]: [jsItem] })
})

it('execFullResponse', async () => {
const result = await request.execFullResponse().toPromise()
expect(batchGetItemsSpy).toHaveBeenCalled()
expect(result).toEqual({
Responses: { [getTableName(SimpleWithPartitionKeyModel)]: [jsItem] },
UnprocessedKeys: {},
})
})

})

})
10 changes: 10 additions & 0 deletions src/dynamo/default-table-name-resolver.const.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Observable } from 'rxjs'
import { DEFAULT_SESSION_VALIDITY_ENSURER } from './default-session-validity-ensurer.const'

describe('DEFAULT_SESSION_VALIDITY_ENSURER', () => {
it('should return an observable without value', async () => {
expect(typeof DEFAULT_SESSION_VALIDITY_ENSURER === 'function').toBeTruthy()
expect(DEFAULT_SESSION_VALIDITY_ENSURER() instanceof Observable).toBeTruthy()
expect(await DEFAULT_SESSION_VALIDITY_ENSURER().toPromise()).toBeUndefined()
})
})
80 changes: 80 additions & 0 deletions src/dynamo/dynamo-rx.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// tslint:disable:no-empty
// tslint:disable:no-unnecessary-callback-wrapper

import { Config, Credentials, DynamoDB } from 'aws-sdk'
import { EMPTY, Observable } from 'rxjs'
import { DEFAULT_SESSION_VALIDITY_ENSURER } from './default-session-validity-ensurer.const'
import { DynamoRx } from './dynamo-rx'
import { SessionValidityEnsurer } from './session-validity-ensurer.type'

describe('dynamo rx', () => {

describe('should call the validity ensurer before each call and return an observable', () => {
let dynamoRx: DynamoRx
let spyValidityEnsurer: SessionValidityEnsurer

beforeEach(() => {
spyValidityEnsurer = jasmine.createSpy().and.returnValue(EMPTY)
dynamoRx = new DynamoRx(spyValidityEnsurer)
})

it('putItem', () => {
expect(dynamoRx.putItem(<any>null) instanceof Observable).toBeTruthy()
expect(spyValidityEnsurer).toHaveBeenCalled()
})
it('getItem', () => {
expect(dynamoRx.getItem(<any>null) instanceof Observable).toBeTruthy()
expect(spyValidityEnsurer).toHaveBeenCalled()
})
it('updateItem', () => {
expect(dynamoRx.updateItem(<any>null) instanceof Observable).toBeTruthy()
expect(spyValidityEnsurer).toHaveBeenCalled()
})
it('deleteItem', () => {
expect(dynamoRx.deleteItem(<any>null) instanceof Observable).toBeTruthy()
expect(spyValidityEnsurer).toHaveBeenCalled()
})
it('batchWriteItem', () => {
expect(dynamoRx.batchWriteItem(<any>null) instanceof Observable).toBeTruthy()
expect(spyValidityEnsurer).toHaveBeenCalled()
})
it('batchGetItems', () => {
expect(dynamoRx.batchGetItems(<any>null) instanceof Observable).toBeTruthy()
expect(spyValidityEnsurer).toHaveBeenCalled()
})
it('scan', () => {
expect(dynamoRx.scan(<any>null) instanceof Observable).toBeTruthy()
expect(spyValidityEnsurer).toHaveBeenCalled()
})
it('query', () => {
const params: DynamoDB.QueryInput = {
TableName: 'tableName',
}
expect(dynamoRx.query({ ...params, KeyConditionExpression: 'blub' }) instanceof Observable).toBeTruthy()
expect(spyValidityEnsurer).toHaveBeenCalled()
expect(() => dynamoRx.query(params)).toThrow()
})
it('makeRequest', () => {
expect(dynamoRx.makeRequest(<any>null) instanceof Observable).toBeTruthy()
expect(spyValidityEnsurer).toHaveBeenCalled()
})
})

it('should call makeRequest with the given params', async () => {
const dynamoRx = new DynamoRx(DEFAULT_SESSION_VALIDITY_ENSURER)
const makeRequest = jasmine.createSpy().and.returnValue({ promise: () => Promise.resolve(null) })
Object.assign(dynamoRx, { dynamoDb: { makeRequest } })

await dynamoRx.makeRequest(<any>{ ok: true }).toPromise()
expect(makeRequest).toHaveBeenCalled()
expect(makeRequest.calls.mostRecent().args[0]).toEqual({ ok: true })
})

it('should update the credentials', () => {
const dynamoRx = new DynamoRx(DEFAULT_SESSION_VALIDITY_ENSURER)
const credentials = new Credentials({ secretAccessKey: '', sessionToken: '', accessKeyId: '' })
dynamoRx.updateAwsConfigCredentials(new Config({ credentials }))
expect(dynamoRx.dynamoDb.config.credentials).toBe(credentials)
})

})
Loading

0 comments on commit 24017b9

Please sign in to comment.