Skip to content

Commit

Permalink
feat(simple-resource-storage): do not hardcode collection names
Browse files Browse the repository at this point in the history
  • Loading branch information
stfsy committed Feb 25, 2024
1 parent d4172e2 commit c3369c9
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 12 deletions.
17 changes: 12 additions & 5 deletions lib/simple-resource-storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -300,24 +300,31 @@ module.exports = class {
/**
* Returns all children of a certain type/collection. Imagine this method walking a tree and returning all leaves at a certain level.
*
* Currently only supports trees with three levels.
*
* @name getAll
* @param {String|Array.<String>} resourceIds resource ids that will added to the resource path i.e. /users/${id}/documents/${id}
* @param {String|Array.<String>} childPath the path of the children to query e.g. /api_clients/queues/messages
* @param {GetOptions} options
* @returns {Promise.<ChildrenAndResourcePaths>}
*/
async getAllChildren(resourceIds, childName, { withMetadata = false, projection } = {}) {
async getAllChildren(resourceIds, childPath, { withMetadata = false, projection } = {}) {
return withActiveSpan(`${name}#get-all-simple-resource-children`, { resourceIds, resourceName: this._collectionName, databaseName: this._databaseName }, async () => {
if (childPath.startsWith('/')) {
childPath = childPath.substring(1)
}
const [parent, child] = childPath.split('/')
if (!parent || !child) {
throw new Error(`childPath with value ${childPath} does not match expected value "parent/child"`)
}

const lookupPipeline = getSingleLookupPipeline({ rootId: this._toStringIfArray(resourceIds), childCollectionName: 'queues' })
const childResourcesPipeline = joinAndQueryChildResourcesPipeline({ parentCollectionName: 'queues', childCollectionName: 'listeners', options: { withMetadata, projection } })
const lookupPipeline = getSingleLookupPipeline({ rootId: this._toStringIfArray(resourceIds), childCollectionName: parent })
const childResourcesPipeline = joinAndQueryChildResourcesPipeline({ parentCollectionName: parent, childCollectionName: child, options: { withMetadata, projection } })
lookupPipeline.push(...childResourcesPipeline)

const collection = await this._getCollection()
const result = await collection.aggregate(lookupPipeline).toArray()

console.log(JSON.stringify(result, null, 2))

if (result.length === 0) {
return result
}
Expand Down
1 change: 0 additions & 1 deletion test/spec/one-to-many-resource-storage.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ describe('OnToManyResourceStorage', () => {
expect(exists).to.be.true
})
it('returns true only if document is being referenced', async () => {
console.log('search', listenerIds.at(2))
const exists = await storage.exists([resourceId, listenerIds.at(2)])
expect(exists).to.be.false
})
Expand Down
16 changes: 10 additions & 6 deletions test/spec/simple-resource-get-all-children.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,31 +114,35 @@ describe('SimpleResourceStorage Get Children', () => {

describe('.getAllChildren', () => {
it('returns all resources known to the parent\'s parent', async () => {
const { children: storedListeners } = await apiClients.getAllChildren([firstClientId], 'listeners')
const { children: storedListeners } = await apiClients.getAllChildren([firstClientId], 'queues/listeners')
expect(storedListeners).to.have.length(3)
})
it('allows childPath with leading slash', async () => {
const { resourcePaths } = await apiClients.getAllChildren([firstClientId], '/queues/listeners')
expect(Object.keys(resourcePaths)).to.have.length(3)
})
it('returns the resource path of all children', async () => {
const { resourcePaths } = await apiClients.getAllChildren([firstClientId], 'listeners')
const { resourcePaths } = await apiClients.getAllChildren([firstClientId], 'queues/listeners')
expect(Object.keys(resourcePaths)).to.have.length(3)
})
it('returns resource path', async () => {
const { resourcePaths } = await apiClients.getAllChildren([firstClientId], 'listeners')
const { resourcePaths } = await apiClients.getAllChildren([firstClientId], 'queues/listeners')
expect(resourcePaths[listenerIds.at(0)]).to.equal(`/queues/${firstQueueId}/listeners/${listenerIds.at(0)}`)
expect(resourcePaths[listenerIds.at(1)]).to.equal(`/queues/${firstQueueId}/listeners/${listenerIds.at(1)}`)
expect(resourcePaths[listenerIds.at(2)]).to.equal(`/queues/${secondQueueId}/listeners/${listenerIds.at(2)}`)
})
it('does not return resources outside of the parent\'s tree', async () => {
const { children: storedListeners } = await apiClients.getAllChildren([firstClientId], 'listeners', { projection: { "name": 0 } })
const { children: storedListeners } = await apiClients.getAllChildren([firstClientId], 'queues/listeners', { projection: { "name": 0 } })
const idsOnly = storedListeners.map((listener) => listener.id)
expect(idsOnly).not.to.contain(listenerIds.at(3))
})
it('returns all resources known to the parent\'s parent 2', async () => {
const { children: storedListeners } = await apiClients.getAllChildren([secondClientId], 'listeners')
const { children: storedListeners } = await apiClients.getAllChildren([secondClientId], 'queues/listeners')
expect(storedListeners).to.have.length(1)
expect(storedListeners.at(0).id).to.equal(listenerIds.at(3))
})
it('returns all resources known to the parent\'s parent and projects fields', async () => {
const { children: storedListeners } = await apiClients.getAllChildren([firstClientId], 'listeners', { projection: { "name": 0 } })
const { children: storedListeners } = await apiClients.getAllChildren([firstClientId], 'queues/listeners', { projection: { "name": 0 } })

expect(storedListeners).to.have.length(3)
storedListeners.forEach((listener) => {
Expand Down

0 comments on commit c3369c9

Please sign in to comment.