Skip to content

Commit

Permalink
fix: xml header consideration for inFile metadata type handler (#811)
Browse files Browse the repository at this point in the history
* feat: ignore xml header absence

* fix: side effect on input of `generatePartialJSON` method

* test: add test when there is no header

* refactor: improve `getRootMetadata` algorithm

* refactor: improve test readibility

* fix: e2e test check

* build: upgrade dependencies

* fix: spell check issue
  • Loading branch information
scolladon authored Mar 18, 2024
1 parent 2ad59dd commit 71b1217
Show file tree
Hide file tree
Showing 6 changed files with 350 additions and 329 deletions.
2 changes: 1 addition & 1 deletion __tests__/functional/delta.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ describe('sgd:source:delta NUTS', () => {
const destructiveChangesLineCount = await getFileLineNumber(
'e2e/expected/destructiveChanges/destructiveChanges.xml'
)
expect(packageLineCount).to.equal(220)
expect(packageLineCount).to.equal(221)
expect(destructiveChangesLineCount).to.equal(130)
expect(result).to.include('"error": null')
expect(result).to.include('"success": true')
Expand Down
233 changes: 123 additions & 110 deletions __tests__/unit/lib/utils/metadataDiff.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,85 @@ const workFlowAttributes = new Map([
['alerts', { xmlName: 'WorkflowAlert', key: 'fullName' }],
])

describe(`MetadataDiff`, () => {
const xmlHeader = { '?xml': { '@_version': '1.0', '@_encoding': 'UTF-8' } }

const alert = {
Workflow: {
'@_xmlns': 'http://soap.sforce.com/2006/04/metadata',
alerts: [
{
fullName: 'TestEmailAlert',
description: 'awesome',
protected: 'false',
recipients: { field: 'OtherEmail', type: 'email' },
senderAddress: '[email protected]',
senderType: 'OrgWideEmailAddress',
template: 'None',
},
{
fullName: 'OtherTestEmailAlert',
description: 'awesome',
protected: 'false',
recipients: { field: 'OtherEmail', type: 'email' },
senderAddress: '[email protected]',
senderType: 'OrgWideEmailAddress',
template: 'None',
},
],
},
}

const alertOther = {
Workflow: {
'@_xmlns': 'http://soap.sforce.com/2006/04/metadata',
alerts: [
{
fullName: 'OtherTestEmailAlert',
description: 'awesome',
protected: 'false',
recipients: { field: 'OtherEmail', type: 'email' },
senderAddress: '[email protected]',
senderType: 'OrgWideEmailAddress',
template: 'None',
},
],
},
}

const alertTest = {
Workflow: {
'@_xmlns': 'http://soap.sforce.com/2006/04/metadata',
alerts: {
fullName: 'TestEmailAlert',
description: 'awesome',
protected: 'false',
recipients: { field: 'OtherEmail', type: 'email' },
senderAddress: '[email protected]',
senderType: 'OrgWideEmailAddress',
template: 'None',
},
},
}

const wfBase = {
Workflow: {
'@_xmlns': 'http://soap.sforce.com/2006/04/metadata',
},
}

const unTracked = {
Workflow: {
'@_xmlns': 'http://soap.sforce.com/2006/04/metadata',
unTracked: {
fullName: 'untracked',
},
},
}

describe.each([[{}], [xmlHeader]])(`MetadataDiff`, header => {
let metadataDiff: MetadataDiff
let globalMetadata: MetadataRepository
let work: Work
let alert: any, alertOther: any, alertTest: any, wfBase: any, unTracked: any
beforeAll(async () => {
// eslint-disable-next-line no-undef
globalMetadata = await getGlobalMetadata()
Expand All @@ -47,87 +121,9 @@ describe(`MetadataDiff`, () => {
globalMetadata,
workFlowAttributes
)

alert = {
'?xml': { '@_version': '1.0', '@_encoding': 'UTF-8' },
Workflow: {
'@_xmlns': 'http://soap.sforce.com/2006/04/metadata',
alerts: [
{
fullName: 'TestEmailAlert',
description: 'awesome',
protected: 'false',
recipients: { field: 'OtherEmail', type: 'email' },
senderAddress: '[email protected]',
senderType: 'OrgWideEmailAddress',
template: 'None',
},
{
fullName: 'OtherTestEmailAlert',
description: 'awesome',
protected: 'false',
recipients: { field: 'OtherEmail', type: 'email' },
senderAddress: '[email protected]',
senderType: 'OrgWideEmailAddress',
template: 'None',
},
],
},
}

alertOther = {
'?xml': { '@_version': '1.0', '@_encoding': 'UTF-8' },
Workflow: {
'@_xmlns': 'http://soap.sforce.com/2006/04/metadata',
alerts: [
{
fullName: 'OtherTestEmailAlert',
description: 'awesome',
protected: 'false',
recipients: { field: 'OtherEmail', type: 'email' },
senderAddress: '[email protected]',
senderType: 'OrgWideEmailAddress',
template: 'None',
},
],
},
}

alertTest = {
'?xml': { '@_version': '1.0', '@_encoding': 'UTF-8' },
Workflow: {
'@_xmlns': 'http://soap.sforce.com/2006/04/metadata',
alerts: {
fullName: 'TestEmailAlert',
description: 'awesome',
protected: 'false',
recipients: { field: 'OtherEmail', type: 'email' },
senderAddress: '[email protected]',
senderType: 'OrgWideEmailAddress',
template: 'None',
},
},
}

wfBase = {
'?xml': { '@_version': '1.0', '@_encoding': 'UTF-8' },
Workflow: {
'@_xmlns': 'http://soap.sforce.com/2006/04/metadata',
},
}

unTracked = {
'?xml': { '@_version': '1.0', '@_encoding': 'UTF-8' },
Workflow: {
'@_xmlns': 'http://soap.sforce.com/2006/04/metadata',
unTracked: {
fullName: 'untracked',
},
},
}
})

describe('compare', () => {
describe(`compare with ${JSON.stringify(header)} header`, () => {
it('does not detect null file content', async () => {
// Arrange
mockedParseXmlFileToJson.mockResolvedValueOnce('')
Expand All @@ -143,8 +139,11 @@ describe(`MetadataDiff`, () => {

it('does not detect not tracked elements', async () => {
// Arrange
mockedParseXmlFileToJson.mockResolvedValueOnce(unTracked)
mockedParseXmlFileToJson.mockResolvedValueOnce(wfBase)
mockedParseXmlFileToJson.mockResolvedValueOnce({
...header,
...unTracked,
})
mockedParseXmlFileToJson.mockResolvedValueOnce({ ...header, ...wfBase })

// Act
const { added, deleted } = await metadataDiff.compare('file/path')
Expand All @@ -156,8 +155,8 @@ describe(`MetadataDiff`, () => {

it('detects added elements', async () => {
// Arrange
mockedParseXmlFileToJson.mockResolvedValueOnce(alert)
mockedParseXmlFileToJson.mockResolvedValueOnce(wfBase)
mockedParseXmlFileToJson.mockResolvedValueOnce({ ...header, ...alert })
mockedParseXmlFileToJson.mockResolvedValueOnce({ ...header, ...wfBase })

// Act
const { added, deleted } = await metadataDiff.compare('file/path')
Expand All @@ -170,8 +169,8 @@ describe(`MetadataDiff`, () => {
})
it('detects removed elements', async () => {
// Arrange
mockedParseXmlFileToJson.mockResolvedValueOnce(wfBase)
mockedParseXmlFileToJson.mockResolvedValueOnce(alert)
mockedParseXmlFileToJson.mockResolvedValueOnce({ ...header, ...wfBase })
mockedParseXmlFileToJson.mockResolvedValueOnce({ ...header, ...alert })

// Act
const { added, deleted } = await metadataDiff.compare('file/path')
Expand All @@ -186,7 +185,7 @@ describe(`MetadataDiff`, () => {
it('detects deleted file', async () => {
// Arrange
mockedParseXmlFileToJson.mockResolvedValueOnce('')
mockedParseXmlFileToJson.mockResolvedValueOnce(alert)
mockedParseXmlFileToJson.mockResolvedValueOnce({ ...header, ...alert })

// Act
const { added, deleted } = await metadataDiff.compare('file/path')
Expand All @@ -200,8 +199,12 @@ describe(`MetadataDiff`, () => {

it('detects modified elements', async () => {
// Arrange
mockedParseXmlFileToJson.mockResolvedValueOnce(alertTest)
mockedParseXmlFileToJson.mockResolvedValueOnce({
...header,
...alertTest,
})
mockedParseXmlFileToJson.mockResolvedValueOnce({
...header,
...alertTest,
Workflow: {
...alertTest.Workflow,
Expand All @@ -217,57 +220,61 @@ describe(`MetadataDiff`, () => {
expect(added.get('WorkflowAlert')).toEqual(new Set(['TestEmailAlert']))
})
})
describe('prune', () => {
describe(`prune with ${JSON.stringify(header)} header`, () => {
it('given one element added, the generated file contains only this element', async () => {
// Arrange
mockedParseXmlFileToJson.mockResolvedValueOnce(alert)
mockedParseXmlFileToJson.mockResolvedValueOnce(alertTest)
mockedParseXmlFileToJson.mockResolvedValueOnce({ ...header, ...alert })
mockedParseXmlFileToJson.mockResolvedValueOnce({
...header,
...alertTest,
})
await metadataDiff.compare('file/path')

// Act
const { isEmpty } = metadataDiff.prune()

// Assert
expect(convertJsonToXml).toHaveBeenCalledWith(alertOther)
expect(convertJsonToXml).toHaveBeenCalledWith({
...header,
...alertOther,
})
expect(isEmpty).toBe(false)
})
it('given every element deleted, the generated file is empty', async () => {
// Arrange
mockedParseXmlFileToJson.mockResolvedValueOnce(alertTest)
mockedParseXmlFileToJson.mockResolvedValueOnce(alert)
mockedParseXmlFileToJson.mockResolvedValueOnce({ ...header, ...wfBase })
mockedParseXmlFileToJson.mockResolvedValueOnce({ ...header, ...alert })
await metadataDiff.compare('file/path')

// Act
const { isEmpty } = metadataDiff.prune()

// Assert
expect(convertJsonToXml).toHaveBeenCalledWith({
...wfBase,
Workflow: {
...wfBase.Workflow,
alerts: [],
},
})
expect(convertJsonToXml).toHaveBeenCalledWith({ ...header, ...wfBase })
expect(isEmpty).toBe(true)
})
it('given file contains only new element, it keeps the file identical', async () => {
// Arrange
mockedParseXmlFileToJson.mockResolvedValueOnce(alert)
mockedParseXmlFileToJson.mockResolvedValueOnce(wfBase)
mockedParseXmlFileToJson.mockResolvedValueOnce({ ...header, ...alert })
mockedParseXmlFileToJson.mockResolvedValueOnce({ ...header, ...wfBase })
await metadataDiff.compare('file/path')

// Act
const { isEmpty } = metadataDiff.prune()

// Assert
expect(convertJsonToXml).toHaveBeenCalledWith(alert)
expect(convertJsonToXml).toHaveBeenCalledWith({ ...header, ...alert })
expect(isEmpty).toBe(false)
})

it('given one element modified, the generated file contains only this element', async () => {
// Arrange
mockedParseXmlFileToJson.mockResolvedValueOnce(alertOther)
mockedParseXmlFileToJson.mockResolvedValueOnce({
...header,
...alertOther,
})
mockedParseXmlFileToJson.mockResolvedValueOnce({
...header,
...alertOther,
Workflow: {
...alertOther.Workflow,
Expand All @@ -280,21 +287,27 @@ describe(`MetadataDiff`, () => {
const { isEmpty } = metadataDiff.prune()

// Assert
expect(convertJsonToXml).toHaveBeenCalledWith(alertOther)
expect(convertJsonToXml).toHaveBeenCalledWith({
...header,
...alertOther,
})
expect(isEmpty).toBe(false)
})

it('given untracked element, nothing trackable changed, the generated file contains untracked elements', async () => {
// Arrange
mockedParseXmlFileToJson.mockResolvedValueOnce(unTracked)
mockedParseXmlFileToJson.mockResolvedValueOnce(wfBase)
mockedParseXmlFileToJson.mockResolvedValueOnce({
...header,
...unTracked,
})
mockedParseXmlFileToJson.mockResolvedValueOnce({ ...header, ...wfBase })
await metadataDiff.compare('file/path')

// Act
const { isEmpty } = metadataDiff.prune()

// Assert
expect(convertJsonToXml).toHaveBeenCalledWith(unTracked)
expect(convertJsonToXml).toHaveBeenCalledWith({ ...header, ...unTracked })
expect(isEmpty).toBe(false)
})
})
Expand Down
Loading

0 comments on commit 71b1217

Please sign in to comment.