8000 MIG-109: split getStudyManifest function as per requirement by davideaquaro · Pull Request #372 · Medable/mdctl · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

MIG-109: split getStudyManifest function as per requirement #372

New issue
8000

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

Merged
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
243 changes: 243 additions & 0 deletions packages/mdctl-axon-tools/__tests__/MIG-109/MIG-109.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
/* 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-109 - Test StudyManifestTools ', () => {

let manifestTools
const mockGetExportedObjects = jest.fn(() => []),
existingStudy = {
_id: '1',
c_name: 'Study',
c_key: 'abc'
},
hasNextStudyMock = jest.fn(() => true),
nextStudyMock = jest.fn(() => existingStudy),
hasNextStudySchema = jest.fn(() => true),
nextStudySchemaMock = jest.fn(() => ({ _id: '1', object: 'object', properties: [{ name: 'c_no_pii' }] })),
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'
}],
dummyReferences = [
{
name: 'c_study',
array: false,
object: 'c_study',
type: 'Reference',
required: false
}
],
org = {
objects: {
c_study: {
readOne: () => ({
skipAcl: () => ({
grant: () => ({
paths: () => ({
hasNext: hasNextStudyMock,
next: nextStudyMock
})
})
})
})
},
object: {
find: () => ({
10000 skipAcl: () => ({
grant: () => ({
paths: () => ({
hasNext: hasNextStudySchema,
next: nextStudySchemaMock
})
})
})
})
}
}
}

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

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

it('Test study manifest creation', async() => {
const manifest = {
object: 'manifest',
dependencies: false,
exportOwner: false,
importOwner: false,
c_study: {
includes: [
'key-001'
]
},
c_dummy_object: {
includes: [
'key-002'
]
},
c_task: {
includes: [
'key-003',
'key-004'
]
},
c_step: {
includes: [
'key-005',
'key-006'
]
}
},
ingestTransform = fs.readFileSync(`${__dirname}/../../packageScripts/ingestTransform.js`).toString()

jest.spyOn(StudyManifestTools.prototype, 'getFirstStudy').mockImplementation(() => org)
jest.spyOn(StudyManifestTools.prototype, 'getOrgObjectInfo').mockImplementation(() => dummyReferences)
jest.spyOn(StudyManifestTools.prototype, 'validateReferences').mockImplementation(() => entities)
jest.spyOn(StudyManifestTools.prototype, 'createManifest').mockImplementation(() => manifest)

// eslint-disable-next-line one-var
const manifestAndDeps = await manifestTools.buildManifestAndDependencies()

expect(manifestAndDeps.manifest)
.toStrictEqual(manifest)
expect(manifestAndDeps.removedEntities)
.toBeUndefined()
expect(manifestAndDeps.mappingScript)
.toBeUndefined()
expect(manifestAndDeps.ingestTransform)
.toStrictEqual(ingestTransform)
})

it('Test task manifest creation', async() => {
const manifest = {
object: 'manifest',
dependencies: false,
exportOwner: false,
importOwner: false,
c_task: {
includes: [
'key-003',
'key-004'
]
},
c_step: {
includes: [
'key-005',
'key-006'
]
}
}

jest.spyOn(StudyManifestTools.prototype, 'getOrgObjectInfo').mockImplementation(() => dummyReferences)
jest.spyOn(StudyManifestTools.prototype, 'validateReferences').mockImplementation(() => entities)
jest.spyOn(StudyManifestTools.prototype, 'createManifest').mockImplementation(() => manifest)

// eslint-disable-next-line one-var
const manifestAndDeps = await manifestTools.buildTaskManifestAndDependencies(['619aaaafe44c6e01003f7313', '61981246ca9563010037bfa8'])

expect(manifestAndDeps.manifest)
.toStrictEqual(manifest)
expect(manifestAndDeps.removedEntities)
.toBeUndefined()
})

it('Test consent manifest creation', async() => {
const manifest = {
object: 'manifest',
dependencies: false,
exportOwner: false,
importOwner: false,
ec__document_template: {
includes: [
'key-007',
'key-008'
]
},
ec__default_document_css: {
includes: [
'key-009'
]
},
ec__knowledge_check: {
includes: [
'key-010',
'key-011'
]
}
}
jest.spyOn(StudyManifestTools.prototype, 'getOrgObjectInfo').mockImplementation(() => dummyReferences)
jest.spyOn(StudyManifestTools.prototype, 'validateReferences').mockImplementation(() => entities)
jest.spyOn(StudyManifestTools.prototype, 'createManifest').mockImplementation(() => manifest)

// eslint-disable-next-line one-var
const manifestAndDeps = await manifestTools.buildConsentManifestAndDependencies(['61981246ca9592ee0e41a3dd', '61980eb292466ea32e087378'])

expect(manifestAndDeps.manifest)
.toStrictEqual(manifest)
expect(manifestAndDeps.removedEntities)
.toBeUndefined()
})
})
93 changes: 62 additions & 31 deletions packages/mdctl-axon-tools/lib/StudyManifestTools.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,29 +125,58 @@ class StudyManifestTools {

async getStudyManifest() {
Copy link
Contributor
@nahueld nahueld May 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also noticed that we have some code duplication for the other mdctl tasks, check

  • getTasksManifest
  • getConsentsManifest

For both cases we could split the logic too (that is have writing logic and processing logic decoupled), this will be really convenient for the next release that we are going to be using those other more granular exports

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @nahueld is it ok for you if I create another Jira to keep track of this as I guess we probably don't want to overlap with the original requirement?

Copy link
Contributor
@nahueld nahueld May 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok let's update the ticket to reflect this, given that this is an internal task we are ok adjusting the requirements

console.log('Building Manifest')
const manifestAndDeps = await this.buildManifestAndDependencies()
await this.writeStudyToDisk(manifestAndDeps)
return manifestAndDeps
}

async getFirstStudy(org) {
const study = await org.objects.c_study.readOne().execute()
return study
}

async getOrgAndReferences() {
const { client } = privatesAccessor(this),
driver = new Driver(client),
org = new Org(driver),
// eslint-disable-next-line camelcase
{ c_study } = org.objects,
study = await c_study.readOne()
.execute(),
{ orgReferenceProps } = await this.getOrgObjectInfo(org),
{ orgReferenceProps } = await this.getOrgObjectInfo(org)
return { org, orgReferenceProps }
}

validateAndCreateManifest(allEntities, orgReferenceProps, ignore = []) {
const { outputEntities, removedEntities } = this
.validateReferences(allEntities, orgReferenceProps, ignore),
manifest = this.createManifest(outputEntities)

return { manifest, removedEntities }
}

async buildManifestAndDependencies() {
const { org, orgReferenceProps } = await this.getOrgAndReferences(),
study = await this.getFirstStudy(org),
allEntities = [study, ...await this.getStudyManifestEntities(org, study, orgReferenceProps)],
{ outputEntities, removedEntities } = this.validateReferences(allEntities, orgReferenceProps),
manifest = this.createManifest(outputEntities),
mappingScript = await getMappingScript(org)
{ manifest, removedEntities } = this.validateAndCreateManifest(allEntities, orgReferenceProps),
mappingScript = await getMappingScript(org),
ingestTransform = fs.readFileSync(`${__dirname}/../packageScripts/ingestTransform.js`)

return {
manifest,
removedEntities,
mappingScript,
ingestTransform: ingestTransform.toString()
}
}

async writeStudyToDisk({
manifest, removedEntities, mappingScript, ingestTransform
}) {
let extraConfig

if (mappingScript) {
extraConfig = this.writeInstallAfterScript(mappingScript)
}

this.writeIssues(removedEntities)
this.writePackage('study', extraConfig)

return { manifest, removedEntities }
this.writeToDisk('study', removedEntities, extraConfig)
}

writeInstallAfterScript(mappingScript) {
Expand All @@ -169,38 +198,40 @@ class StudyManifestTools {
return packageReference
}

writeToDisk(entityType, removedEntities, extraConfig) {
this.writeIssues(removedEntities)
this.writePackage(entityType, extraConfig)
}

async getTasksManifest(taskIds) {
console.log('Building Manifest')
const { client } = privatesAccessor(this),
driver = new Driver(client),
org = new Org(driver),
{ orgReferenceProps } = await this.getOrgObjectInfo(org),
allEntities = await this.getTaskManifestEntities(org, taskIds, orgReferenceProps),
{ outputEntities, removedEntities } = this.validateReferences(allEntities, orgReferenceProps, ['c_tasks']),
manifest = this.createManifest(outputEntities)
const manifestAndDeps = await this.buildTaskManifestAndDependencies(taskIds)
this.writeToDisk('task', manifestAndDeps.removedEntities)
return manifestAndDeps
}

this.writeIssues(removedEntities)
this.writePackage('task')
async buildTaskManifestAndDependencies(taskIds) {
const { org, orgReferenceProps } = await this.getOrgAndReferences(),
allEntities = await this.getTaskManifestEntities(org, taskIds, orgReferenceProps),
{ manifest, removedEntities } = this.validateAndCreateManifest(allEntities, orgReferenceProps, ['c_tasks'])

return { manifest, removedEntities }

}

async getConsentsManifest(consentIds) {
console.log('Building Manifest')
const { client } = privatesAccessor(this),
driver = new Driver(client),
org = new Org(driver),
{ orgReferenceProps } = await this.getOrgObjectInfo(org),
allEntities = await this.getConsentManifestEntities(org, consentIds, orgReferenceProps),
{ outputEntities, removedEntities } = this.validateReferences(allEntities, orgReferenceProps, ['ec__document_templates']),
manifest = this.createManifest(outputEntities)
const manifestAndDeps = await this.buildConsentManifestAndDependencies(consentIds)
this.writeToDisk('consent', manifestAndDeps.removedEntities)
return manifestAndDeps
}

this.writeIssues(removedEntities)
this.writePackage('consent')
async buildConsentManifestAndDependencies(consentIds) {
const { org, orgReferenceProps } = await this.getOrgAndReferences(),
allEntities = await this.getConsentManifestEntities(org, consentIds, orgReferenceProps),
{ manifest, removedEntities } = this.validateAndCreateManifest(allEntities, orgReferenceProps, ['ec__document_templates'])

return { manifest, removedEntities }

}

createManifest(entities) {
Expand Down
0