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

feat: prune layoutAssignments, loginHours and loginIpRanges #954

Merged
merged 7 commits into from
Dec 6, 2024
27 changes: 0 additions & 27 deletions __tests__/unit/lib/utils/fxpHelper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { describe, expect, it, jest } from '@jest/globals'
import type { Config } from '../../../../src/types/config'
import { readPathFromGit } from '../../../../src/utils/fsHelper'
import {
asArray,
convertJsonToXml,
parseXmlFileToJson,
xml2Json,
Expand All @@ -15,32 +14,6 @@ const mockedReadPathFromGit = jest.mocked(readPathFromGit)
jest.mock('../../../../src/utils/fsHelper')

describe('fxpHelper', () => {
describe('asArray', () => {
describe('when called with array', () => {
// Arrange
const expected = ['test']

it('returns the same array', () => {
// Act
const actual = asArray(expected)

// Assert
expect(actual).toBe(expected)
})
})
describe('when called with object', () => {
// Arrange
const expected = 'test'

it('returns the array with this object', () => {
// Act
const actual = asArray(expected)

// Assert
expect(actual).toEqual([expected])
})
})
})
describe('parseXmlFileToJson', () => {
const config: Config = {
from: '',
Expand Down
253 changes: 244 additions & 9 deletions __tests__/unit/lib/utils/metadataDiff.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import { describe, expect, it, jest } from '@jest/globals'

import { MetadataRepository } from '../../../../src/metadata/MetadataRepository'
import { getInFileAttributes } from '../../../../src/metadata/metadataManager'
import { SharedFileMetadata } from '../../../../src/types/metadata'
import type { Work } from '../../../../src/types/work'
import {
convertJsonToXml,
Expand All @@ -22,12 +24,105 @@ jest.mock('../../../../src/utils/fxpHelper', () => {
})
const mockedParseXmlFileToJson = jest.mocked(parseXmlFileToJson)

const workFlowAttributes = new Map([
['alerts', { xmlName: 'WorkflowAlert', key: 'fullName' }],
])

const xmlHeader = { '?xml': { '@_version': '1.0', '@_encoding': 'UTF-8' } }

const emptyProfile = {
Profile: {
'@_xmlns': 'http://soap.sforce.com/2006/04/metadata',
layoutAssignments: [],
loginHours: [],
loginIpRanges: [],
},
}

const profile = {
Profile: {
'@_xmlns': 'http://soap.sforce.com/2006/04/metadata',
layoutAssignments: [
{
layout: 'test-layout',
recordType: 'test-recordType',
},
],
loginHours: [
{
mondayStart: '300',
mondayEnd: '500',
},
],
loginIpRanges: [
{
description: 'ip range description',
endAddress: '168.0.0.1',
startAddress: '168.0.0.255',
},
],
},
}

const profileChanged = {
Profile: {
'@_xmlns': 'http://soap.sforce.com/2006/04/metadata',
layoutAssignments: [
{
layout: 'another-test-layout',
recordType: 'test-recordType',
},
],
loginHours: [
{
mondayStart: '400',
mondayEnd: '500',
},
],
loginIpRanges: [
{
description: 'ip range description',
endAddress: '168.0.0.0',
startAddress: '168.0.0.255',
},
],
},
}

const profileAdded = {
Profile: {
'@_xmlns': 'http://soap.sforce.com/2006/04/metadata',
layoutAssignments: [
{
layout: 'test-layout',
recordType: 'test-recordType',
},
{
layout: 'another-test-layout',
recordType: 'test-recordType',
},
],
loginHours: [
{
mondayStart: '300',
mondayEnd: '500',
},
{
tuesdayStart: '400',
tuesdayEnd: '500',
},
],
loginIpRanges: [
{
description: 'ip range description',
endAddress: '168.0.0.0',
startAddress: '168.0.0.255',
},
{
description: 'complete ip range description',
endAddress: '168.0.0.1',
startAddress: '168.0.0.255',
},
],
},
}

const alert = {
Workflow: {
'@_xmlns': 'http://soap.sforce.com/2006/04/metadata',
Expand Down Expand Up @@ -104,20 +199,18 @@ const unTracked = {
describe.each([[{}], [xmlHeader]])(`MetadataDiff`, header => {
let metadataDiff: MetadataDiff
let globalMetadata: MetadataRepository
let inFileAttribute: Map<string, SharedFileMetadata>
let work: Work
beforeAll(async () => {
globalMetadata = await getGlobalMetadata()
inFileAttribute = getInFileAttributes(globalMetadata)
})
beforeEach(() => {
jest.resetAllMocks()
work = getWork()
work.config.from = 'from'
work.config.to = 'to'
metadataDiff = new MetadataDiff(
work.config,
globalMetadata,
workFlowAttributes
)
metadataDiff = new MetadataDiff(work.config, inFileAttribute)
})

describe(`compare with ${JSON.stringify(header)} header`, () => {
Expand Down Expand Up @@ -291,6 +384,148 @@ describe.each([[{}], [xmlHeader]])(`MetadataDiff`, header => {
expect(isEmpty).toBe(false)
})

describe('key less elements', () => {
it('given one element modified, the generated file contains the difference', async () => {
/*
Cas loginHours et loginIpRanges = si les tableaux sont égaux => on met tableau vide sinon on met le dernier tableau
Cas layout : ajouter tous les éléments de to qui ne sont pas dans from
*/
// Arrange
mockedParseXmlFileToJson.mockResolvedValueOnce({
...header,
...profileChanged,
})
mockedParseXmlFileToJson.mockResolvedValueOnce({
...header,
...profile,
})
await metadataDiff.compare('file/path')

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

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

it('given added elements, the generated file contains the difference', async () => {
/*
Cas loginHours et loginIpRanges = si les tableaux sont égaux => on met tableau vide sinon on met le dernier tableau
Cas layout : ajouter tous les éléments de to qui ne sont pas dans from
*/
// Arrange
mockedParseXmlFileToJson.mockResolvedValueOnce({
...header,
...profileAdded,
})
mockedParseXmlFileToJson.mockResolvedValueOnce({
...header,
...profile,
})
await metadataDiff.compare('file/path')

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

// Assert
expect(convertJsonToXml).toHaveBeenCalledWith({
...header,
...{
Profile: {
'@_xmlns': 'http://soap.sforce.com/2006/04/metadata',
layoutAssignments: [
{
layout: 'another-test-layout',
recordType: 'test-recordType',
},
],
loginHours: [
{
mondayStart: '300',
mondayEnd: '500',
},
{
tuesdayStart: '400',
tuesdayEnd: '500',
},
],
loginIpRanges: [
{
description: 'ip range description',
endAddress: '168.0.0.0',
startAddress: '168.0.0.255',
},
{
description: 'complete ip range description',
endAddress: '168.0.0.1',
startAddress: '168.0.0.255',
},
],
},
},
})
expect(isEmpty).toBe(false)
})

it('given no element added nor modified, the generated file contains empty definition', async () => {
/*
Cas loginHours et loginIpRanges = si les tableaux sont égaux => on met tableau vide sinon on met le dernier tableau
Cas layout : ajouter tous les éléments de to qui ne sont pas dans from
*/
// Arrange
mockedParseXmlFileToJson.mockResolvedValueOnce({
...header,
...profile,
})
mockedParseXmlFileToJson.mockResolvedValueOnce({
...header,
...profile,
})
await metadataDiff.compare('file/path')

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

// Assert
expect(convertJsonToXml).toHaveBeenCalledWith({
...header,
...emptyProfile,
})
expect(isEmpty).toBe(true)
})

it('given no element added nor modified, the generated file contains empty profile', async () => {
/*
Cas loginHours et loginIpRanges = si les tableaux sont égaux => on met tableau vide sinon on met le dernier tableau
Cas layout : ajouter tous les éléments de to qui ne sont pas dans from
*/
// Arrange
mockedParseXmlFileToJson.mockResolvedValueOnce({
...header,
...emptyProfile,
})
mockedParseXmlFileToJson.mockResolvedValueOnce({
...header,
...profile,
})
await metadataDiff.compare('file/path')

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

// Assert
expect(convertJsonToXml).toHaveBeenCalledWith({
...header,
...emptyProfile,
})
expect(isEmpty).toBe(true)
})
})

it('given untracked element, nothing trackable changed, the generated file contains untracked elements', async () => {
// Arrange
mockedParseXmlFileToJson.mockResolvedValueOnce({
Expand Down
28 changes: 26 additions & 2 deletions src/metadata/a48.json
Original file line number Diff line number Diff line change
Expand Up @@ -1505,8 +1505,7 @@
"xmlTag": "fieldPermissions",
"key": "field",
"excluded": true
},
{
},{
"inFolder": false,
"metaFile": false,
"parentXmlName": "Profile",
Expand All @@ -1515,6 +1514,31 @@
"key": "flow",
"excluded": true
},
{
"inFolder": false,
"metaFile": false,
"parentXmlName": "Profile",
"xmlName": "ProfileLayoutAssignments",
"xmlTag": "layoutAssignments",
"key": "<object>",
"excluded": true
},
{
"inFolder": false,
"metaFile": false,
"parentXmlName": "Profile",
"xmlName": "ProfileLoginHours",
"xmlTag": "loginHours",
"excluded": true
},
{
"inFolder": false,
"metaFile": false,
"parentXmlName": "Profile",
"xmlName": "ProfileLoginIpRange",
"xmlTag": "loginIpRanges",
"excluded": true
},
{
"inFolder": false,
"metaFile": false,
Expand Down
Loading
Loading