diff --git a/packages/jira-adapter/e2e_test/adapter.test.ts b/packages/jira-adapter/e2e_test/adapter.test.ts index 8a0fb8fe46d..fd2d94c07f2 100644 --- a/packages/jira-adapter/e2e_test/adapter.test.ts +++ b/packages/jira-adapter/e2e_test/adapter.test.ts @@ -14,16 +14,21 @@ * limitations under the License. */ import { + Change, + CORE_ANNOTATIONS, DeployResult, Element, getChangeData, InstanceElement, isAdditionChange, + isInstanceChange, isInstanceElement, isObjectType, ModificationChange, ProgressReporter, ReadOnlyElementsSource, + SaltoElementError, + SaltoError, toChange, } from '@salto-io/adapter-api' import { logger } from '@salto-io/logging' @@ -41,6 +46,7 @@ import { findInstance } from './utils' import { getLookUpName } from '../src/reference_mapping' import { getDefaultConfig } from '../src/config/config' import { BEHAVIOR_TYPE } from '../src/constants' +import { FIELD_CONTEXT_TYPE_NAME, FIELD_TYPE_NAME } from '../src/filters/fields/constants' const { awu } = collections.asynciterable const { replaceInstanceTypeForDeploy } = elementUtils.ducktype @@ -134,6 +140,7 @@ each([ let modifyDeployResults: DeployResult[] let addInstanceGroups: InstanceElement[][] let modifyInstanceGroups: ModificationChange[][] + let elements: Element[] beforeAll(async () => { elementsSource = buildElementsSourceFromElements(fetchedElements) @@ -202,9 +209,9 @@ each([ }) it('fetch should return the new changes', async () => { - const { elements } = await adapter.fetch({ + ;({ elements } = await adapter.fetch({ progressReporter: { reportProgress: () => null }, - }) + })) const resolvedFetchedElements = await Promise.all(elements.map(e => resolveValues(e, getLookUpName))) const { scriptRunnerApiDefinitions } = getDefaultConfig({ isDataCenter }) @@ -245,6 +252,7 @@ each([ .flatMap(res => res.appliedChanges) .filter(isAdditionChange) .map(change => toChange({ before: getChangeData(change) })) + .filter(isInstanceChange) removalChanges.forEach(change => { const instance = getChangeData(change) removalChanges @@ -256,32 +264,60 @@ each([ }) }) - addDeployResults = await Promise.all( - removalChanges.map(change => { - try { - return adapter.deploy({ - changeGroup: { - groupID: getChangeData(change).elemID.getFullName(), - changes: [change], - }, - progressReporter: nullProgressReporter, - }) - } catch (e) { - if (String(e).includes('status code 404')) { - return { - errors: [], - appliedChanges: [], + const deployChanges = async ( + changes: Change[], + catchCondition: (e: unknown) => boolean, + ): Promise<(SaltoError | SaltoElementError)[]> => { + const deployResults = await Promise.all( + changes.map(change => { + try { + return adapter.deploy({ + changeGroup: { + groupID: getChangeData(change).elemID.getFullName(), + changes: [change], + }, + progressReporter: nullProgressReporter, + }) + } catch (e) { + if (catchCondition(e)) { + return { + errors: [], + appliedChanges: [], + } } + throw e } - throw e - } - }), - ) + }), + ) - const errors = addDeployResults.flatMap(res => res.errors) + return deployResults.flatMap(res => res.errors) + } + + const errors = await deployChanges(removalChanges, (e: unknown) => String(e).includes('status code 404')) if (errors.length) { throw new Error(`Failed to clean e2e changes: ${errors.map(e => safeJsonStringify(e)).join(', ')}`) } + const removalInstancesNames = removalChanges.map(change => getChangeData(change).elemID.getFullName()) + const allOssCreatedElements = elements + .filter(isInstanceElement) + .filter(instance => instance.elemID.name.includes('createdByOssE2e')) + .filter(instance => !removalInstancesNames.includes(instance.elemID.getFullName())) + .filter(instance => instance.elemID.typeName !== FIELD_TYPE_NAME || instance.value.isLocked === false) // do not delete locked fields + .filter( + instance => + instance.elemID.typeName !== FIELD_CONTEXT_TYPE_NAME || + instance.annotations[CORE_ANNOTATIONS.PARENT]?.[0].value.isLocked === false, + ) // do not delete contexts of locked fields + .map(instance => toChange({ before: instance })) + + if (!isDataCenter) { + const allRemovalErrors = await deployChanges(allOssCreatedElements, () => true) // do not fail on errors + if (allRemovalErrors.length) { + throw new Error( + `Failed to clean older e2e changes: ${allRemovalErrors.map(e => safeJsonStringify(e)).join(', ')}`, + ) + } + } }) }) }) diff --git a/packages/jira-adapter/e2e_test/instances/datacenter/index.ts b/packages/jira-adapter/e2e_test/instances/datacenter/index.ts index 844e66c25c2..c68ebc0a8c0 100644 --- a/packages/jira-adapter/e2e_test/instances/datacenter/index.ts +++ b/packages/jira-adapter/e2e_test/instances/datacenter/index.ts @@ -18,16 +18,17 @@ import { AUTOMATION_TYPE, ISSUE_TYPE_NAME, PRIORITY_SCHEME_TYPE_NAME, WORKFLOW_T import { findType } from '../../utils' import { createAutomationValues } from './automation' import { createKanbanBoardValues, createScrumBoardValues } from './board' +import { createFieldConfigurationValues } from './fieldConfiguration' import { createFilterValues } from './filter' import { createPrioritySchemeValues } from './priorityScheme' import { createWorkflowValues } from './workflow' export const createInstances = (randomString: string, fetchedElements: Element[]): InstanceElement[][] => { - // const fieldConfiguration = new InstanceElement( - // randomString, - // findType('FieldConfiguration', fetchedElements), - // createFieldConfigurationValues(randomString), - // ) + const fieldConfiguration = new InstanceElement( + randomString, + findType('FieldConfiguration', fetchedElements), + createFieldConfigurationValues(randomString), + ) const issueType = new InstanceElement(`IT_${randomString}`, findType(ISSUE_TYPE_NAME, fetchedElements), { description: randomString, name: `IT_${randomString}`, @@ -71,7 +72,7 @@ export const createInstances = (randomString: string, fetchedElements: Element[] ) return [ - // [fieldConfiguration], + [fieldConfiguration], [automation], [workflow], [kanbanBoard],