Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MIG-156 : added flag to exclude eTemplates from study export #436

Merged
merged 1 commit into from
Jan 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 17 additions & 14 deletions packages/mdctl-axon-tools/__tests__/MIG-154/MIG-154.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,24 @@ describe('MIG-154 - Check new methods', () => {
})

it('Test getKeyName', async() => {
const orgObjects = {
find: (filter) => {
const mockedObjects = [
{
name: 'c_task',
uniqueKey: 'c_key'
},
{
name: 'c_visit',
uniqueKey: ''
}
]
return mockedObjects.filter(e => e.name === filter.name)
const orgObjects = [
{
name: 'c_fault',
uniqueKey: 'c_key'
},
{
name: 'c_group',
uniqueKey: 'c_key'
},
{
name: 'c_task',
uniqueKey: 'c_key'
},
{
name: 'c_visit',
uniqueKey: ''
}
}
]

jest.mock('@medable/mdctl-core-utils/privates', () => ({ privatesAccessor: () => ({ orgObjects }) }))
// eslint-disable-next-line global-require
Expand Down
251 changes: 251 additions & 0 deletions packages/mdctl-axon-tools/__tests__/MIG-156/MIG-156.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
/* eslint-disable import/order */

jest.mock('@medable/mdctl-api-driver', () => ({ Driver: class {} }), { virtual: true })
jest.mock('@medable/mdctl-api-driver/lib/cortex.object', () => ({ Object: class {}, Org: class {} }), { virtual: true })
jest.mock('../../lib/mappings')

const fs = require('fs'),
StudyManifestTools = require('../../lib/StudyManifestTools')

describe('MIG-156 - Test eTemplate exclusion in StudyManifestTools', () => {

let manifestTools
const mockGetExportedObjects = jest.fn(() => []),
existingStudy = {
_id: '1',
c_name: 'Study',
c_key: 'abc'
},
hasNextStudyMock = jest.fn(() => true),
nextStudyMock = jest.fn(() => existingStudy),
entities = [{
_id: '615bcd016631cc0100d2766c',
object: 'c_study',
c_key: 'key-001'
},
{
_id: '615b60d1bf2e4301008f4d68',
object: 'c_dummy_object',
c_key: 'key-002'
},
{
_id: '619aaaafe44c6e01003f7313',
object: 'c_task',
c_key: 'key-003'
},
{
_id: '61981246ca9563010037bfa8',
object: 'c_task',
c_key: 'key-004'
},
{
_id: '61981246ca95714c14e61a8c',
object: 'c_step',
c_key: 'key-005'
},
{
_id: '61981246ca966caef6108f28',
object: 'c_step',
c_key: 'key-006'
},
{
_id: '61981246ca9592ee0e41a3dd',
object: 'ec__document_template',
c_key: 'key-007'
},
{
_id: '61980eb292466ea32e087378',
object: 'ec__document_template',
c_key: 'key-008'
},
{
_id: '6d525cf2e328e7300d97c399',
object: 'ec__default_document_css',
c_key: 'key-009'
},
{
_id: '6d525cfe328e64ac0833baef',
object: 'ec__knowledge_check',
c_key: 'key-010'
},
{
_id: '6d525f2e328e7f1e48262523',
object: 'ec__knowledge_check',
c_key: 'key-011'
},
{
_id: '6d525gbed28e7f1e4826bb76',
object: 'c_visit_schedule',
c_key: 'key-012'
},
{
_id: '6d525gc1408e7f1e4826bb11',
object: 'c_visit',
c_key: 'key-013'
},
{
_id: '6d525gbe28e7fc4ff43c310',
object: 'c_group',
c_key: 'key-014'
},
{
_id: '67725gbe28e7f98ee3c8667',
object: 'c_group_task',
c_key: 'key-015'
}],
dummyReferences = [
{
name: 'c_study',
array: false,
object: 'c_study',
type: 'Reference',
required: false
}
],
org = {
objects: {
c_study: {
readOne: () => ({
execute: () => ({
hasNext: hasNextStudyMock,
next: nextStudyMock
})
})
},
c_task: {
find: () => ({
limit: () => ({
toArray: () => entities.filter(e => e.object === 'c_task')
})
})
},
ec__document_template: {
find: () => ({
limit: () => ({
toArray: () => entities.filter(e => e.object === 'ec__document_template')
})
})
},
object: {
find: () => ({
paths: () => ({
toArray: () => [{ uniqueKey: 'c_key' }]
})
})
}
}
}

beforeAll(async() => {
manifestTools = new StudyManifestTools({})
manifestTools.getExportObjects = mockGetExportedObjects
})

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

it('Test eTemplates not excluded from manifest', async() => {
const manifestEntitiesToCompare = [
{
_id: '619aaaafe44c6e01003f7313',
object: 'c_task',
c_key: 'key-003'
},
{
_id: '61981246ca9563010037bfa8',
object: 'c_task',
c_key: 'key-004'
},
{
_id: '61981246ca95714c14e61a8c',
object: 'c_step',
c_key: 'key-005'
},
{
_id: '61981246ca966caef6108f28',
object: 'c_step',
c_key: 'key-006'
},
{
_id: '61981246ca9592ee0e41a3dd',
object: 'ec__document_template',
c_key: 'key-007'
},
{
_id: '61980eb292466ea32e087378',
object: 'ec__document_template',
c_key: 'key-008'
},
{
_id: '6d525cf2e328e7300d97c399',
object: 'ec__default_document_css',
c_key: 'key-009'
},
{
_id: '6d525cfe328e64ac0833baef',
object: 'ec__knowledge_check',
c_key: 'key-010'
},
{
_id: '6d525f2e328e7f1e48262523',
object: 'ec__knowledge_check',
c_key: 'key-011'
}
],
exportableObject = manifestTools.getAvailableObjectNames(),
keyName = 'c_key'

jest.spyOn(StudyManifestTools.prototype, 'getExportableObjects').mockImplementation(() => exportableObject)
jest.spyOn(StudyManifestTools.prototype, 'getKeyName').mockImplementation(key => ((key === 'ec__document_template') ? 'ec__key' : keyName))
jest.spyOn(StudyManifestTools.prototype, 'getTaskManifestEntities').mockImplementation(() => entities.filter(o => ['c_task', 'c_step', 'c_branch'].includes(o.object)))
jest.spyOn(StudyManifestTools.prototype, 'getConsentManifestEntities').mockImplementation(() => entities.filter(o => ['ec__document_template', 'ec__default_document_css', 'ec__knowledge_check'].includes(o.object)))
jest.spyOn(StudyManifestTools.prototype, 'getObjectIDsArray').mockImplementation(key => entities.filter(o => o.object === key))
jest.spyOn(StudyManifestTools.prototype, 'mapObjectNameToPlural').mockImplementation(key => `${key}s`)
// eslint-disable-next-line one-var, max-len
const manifestEntities = await manifestTools.getStudyManifestEntities(org, existingStudy, {}, dummyReferences, false)

expect(manifestEntities)
.toStrictEqual(manifestEntitiesToCompare)
})

it('Test eTemplates excluded from manifest', async() => {
const manifestEntitiesToCompare = [
{
_id: '619aaaafe44c6e01003f7313',
object: 'c_task',
c_key: 'key-003'
},
{
_id: '61981246ca9563010037bfa8',
object: 'c_task',
c_key: 'key-004'
},
{
_id: '61981246ca95714c14e61a8c',
object: 'c_step',
c_key: 'key-005'
},
{
_id: '61981246ca966caef6108f28',
object: 'c_step',
c_key: 'key-006'
}
],
exportableObject = manifestTools.getAvailableObjectNames(),
keyName = 'c_key'

jest.spyOn(StudyManifestTools.prototype, 'getExportableObjects').mockImplementation(() => exportableObject)
jest.spyOn(StudyManifestTools.prototype, 'getKeyName').mockImplementation(key => ((key === 'ec__document_template') ? 'ec__key' : keyName))
jest.spyOn(StudyManifestTools.prototype, 'getTaskManifestEntities').mockImplementation(() => entities.filter(o => ['c_task', 'c_step', 'c_branch'].includes(o.object)))
jest.spyOn(StudyManifestTools.prototype, 'getConsentManifestEntities').mockImplementation(() => entities.filter(o => ['ec__document_template', 'ec__default_document_css', 'ec__knowledge_check'].includes(o.object)))
jest.spyOn(StudyManifestTools.prototype, 'getObjectIDsArray').mockImplementation(key => entities.filter(o => o.object === key))
jest.spyOn(StudyManifestTools.prototype, 'mapObjectNameToPlural').mockImplementation(key => `${key}s`)
// eslint-disable-next-line one-var, max-len
const manifestEntities = await manifestTools.getStudyManifestEntities(org, existingStudy, {}, dummyReferences, true)

expect(manifestEntities)
.toStrictEqual(manifestEntitiesToCompare)
})

})
50 changes: 28 additions & 22 deletions packages/mdctl-axon-tools/lib/StudyManifestTools.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,9 @@ class StudyManifestTools {
return privatesAccessor(this).orgObjects.find(v => v.pluralName === pluralName).name
}

async getStudyManifest(manifestObject) {
async getStudyManifest(manifestObject, excludeTemplates = false) {
console.log('Building Manifest')
const manifestAndDeps = await this.buildManifestAndDependencies(manifestObject)
const manifestAndDeps = await this.buildManifestAndDependencies(manifestObject, excludeTemplates)
await this.writeStudyToDisk(manifestAndDeps)
return manifestAndDeps
}
Expand All @@ -176,7 +176,12 @@ class StudyManifestTools {
return { manifest, removedEntities }
}

async buildManifestAndDependencies(manifestJSON) {
// This function is to facilitate unit testing
async getMappings(org) {
return getMappingScript(org)
}

async buildManifestAndDependencies(manifestJSON, excludeTemplates = false) {
let ignoreKeys = [],
cleanManifest,
study
Expand All @@ -192,8 +197,8 @@ class StudyManifestTools {
study = await this.getFirstStudy(org)
}

const mappingScript = await getMappingScript(org),
allEntities = await this.getStudyManifestEntities(org, study, cleanManifest, orgReferenceProps),
const mappingScript = await this.getMappings(org),
allEntities = await this.getStudyManifestEntities(org, study, cleanManifest, orgReferenceProps, excludeTemplates),
{ manifest, removedEntities } = this
.validateAndCreateManifest(allEntities, orgReferenceProps, ignoreKeys)

Expand Down Expand Up @@ -300,15 +305,14 @@ class StudyManifestTools {

createManifest(entities) {
const manifest = {
object: 'manifest',
dependencies: false,
exportOwner: false,
importOwner: false
},
{ orgObjects } = privatesAccessor(this)
object: 'manifest',
dependencies: false,
exportOwner: false,
importOwner: false
}

entities.forEach((entity) => {
const { uniqueKey } = orgObjects.find(v => v.name === entity.object)
const uniqueKey = this.getKeyName(entity.object)
if (!manifest[entity.object]) {
manifest[entity.object] = {
includes: []
Expand Down Expand Up @@ -703,11 +707,11 @@ class StudyManifestTools {
}

getKeyName(key) {
return first(privatesAccessor(this).orgObjects.find({ name: key }).map(({ uniqueKey }) => uniqueKey))
return privatesAccessor(this).orgObjects
.find(({ name }) => name === key).uniqueKey
}

async getStudyManifestEntities(org, study, manifestObject, orgReferenceProps) {

async getStudyManifestEntities(org, study, manifestObject, orgReferenceProps, excludeTemplates = false) {
const manifestEntities = [],
// Get all objects that can be exported
exportableObjects = this.getExportableObjects(),
Expand Down Expand Up @@ -736,12 +740,14 @@ class StudyManifestTools {
break
}
case 'ec__document_template': {
// Get the eConsents ID's from the study or the manifest
// econsent template properties are namespaced ec__, rather than c_
const ecProp = property === 'c_study' ? 'ec__study' : property
ids = (await this.getObjectIDsArray(org, key, ecProp, values)).map(v => v._id)
// Load the manifest for the current ID's and their dependencies
objectAndDependencies = await this.getConsentManifestEntities(org, ids, orgReferenceProps)
if (!excludeTemplates) {
// Get the eConsents ID's from the study or the manifest
// econsent template properties are namespaced ec__, rather than c_
const ecProp = property === 'c_study' ? 'ec__study' : property
ids = (await this.getObjectIDsArray(org, key, ecProp, values)).map(v => v._id)
// Load the manifest for the current ID's and their dependencies
objectAndDependencies = await this.getConsentManifestEntities(org, ids, orgReferenceProps)
}
break
}
case 'c_visit_schedule': {
Expand Down Expand Up @@ -788,7 +794,7 @@ class StudyManifestTools {
}
}
// Push the deconstructed object
manifestEntities.push(...objectAndDependencies)
manifestEntities.push(...(objectAndDependencies || []))
}

return manifestEntities
Expand Down
Loading