mcdev 3.1.3 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/.eslintrc.json +67 -7
  2. package/.github/ISSUE_TEMPLATE/bug.yml +2 -1
  3. package/.github/PULL_REQUEST_TEMPLATE.md +5 -3
  4. package/.github/dependabot.yml +14 -0
  5. package/.github/workflows/code-analysis.yml +57 -0
  6. package/.husky/commit-msg +10 -0
  7. package/.husky/post-checkout +5 -0
  8. package/.husky/pre-commit +2 -1
  9. package/.prettierrc +8 -0
  10. package/.vscode/settings.json +1 -1
  11. package/LICENSE +2 -2
  12. package/README.md +134 -45
  13. package/boilerplate/config.json +5 -11
  14. package/boilerplate/files/.prettierrc +8 -0
  15. package/boilerplate/files/.vscode/extensions.json +0 -1
  16. package/boilerplate/files/.vscode/settings.json +28 -2
  17. package/boilerplate/files/README.md +2 -2
  18. package/boilerplate/forcedUpdates.json +10 -0
  19. package/boilerplate/npm-dependencies.json +5 -5
  20. package/docs/dist/documentation.md +2795 -1724
  21. package/jsconfig.json +1 -1
  22. package/lib/Builder.js +166 -75
  23. package/lib/Deployer.js +244 -96
  24. package/lib/MetadataTypeDefinitions.js +2 -0
  25. package/lib/MetadataTypeInfo.js +2 -0
  26. package/lib/Retriever.js +61 -84
  27. package/lib/cli.js +116 -11
  28. package/lib/index.js +241 -561
  29. package/lib/metadataTypes/AccountUser.js +101 -95
  30. package/lib/metadataTypes/Asset.js +677 -248
  31. package/lib/metadataTypes/AttributeGroup.js +23 -12
  32. package/lib/metadataTypes/Automation.js +451 -354
  33. package/lib/metadataTypes/Campaign.js +33 -93
  34. package/lib/metadataTypes/ContentArea.js +31 -11
  35. package/lib/metadataTypes/DataExtension.js +387 -372
  36. package/lib/metadataTypes/DataExtensionField.js +131 -54
  37. package/lib/metadataTypes/DataExtensionTemplate.js +22 -4
  38. package/lib/metadataTypes/DataExtract.js +61 -48
  39. package/lib/metadataTypes/DataExtractType.js +14 -8
  40. package/lib/metadataTypes/Discovery.js +21 -16
  41. package/lib/metadataTypes/Email.js +32 -12
  42. package/lib/metadataTypes/EmailSendDefinition.js +85 -80
  43. package/lib/metadataTypes/EventDefinition.js +61 -43
  44. package/lib/metadataTypes/FileTransfer.js +72 -52
  45. package/lib/metadataTypes/Filter.js +11 -4
  46. package/lib/metadataTypes/Folder.js +149 -117
  47. package/lib/metadataTypes/FtpLocation.js +14 -8
  48. package/lib/metadataTypes/ImportFile.js +61 -64
  49. package/lib/metadataTypes/Interaction.js +19 -4
  50. package/lib/metadataTypes/List.js +54 -13
  51. package/lib/metadataTypes/MetadataType.js +668 -454
  52. package/lib/metadataTypes/MobileCode.js +46 -0
  53. package/lib/metadataTypes/MobileKeyword.js +114 -0
  54. package/lib/metadataTypes/Query.js +204 -103
  55. package/lib/metadataTypes/Role.js +76 -61
  56. package/lib/metadataTypes/Script.js +145 -81
  57. package/lib/metadataTypes/SetDefinition.js +20 -8
  58. package/lib/metadataTypes/TriggeredSendDefinition.js +78 -58
  59. package/lib/metadataTypes/definitions/Asset.definition.js +21 -10
  60. package/lib/metadataTypes/definitions/AttributeGroup.definition.js +12 -0
  61. package/lib/metadataTypes/definitions/Automation.definition.js +10 -5
  62. package/lib/metadataTypes/definitions/Campaign.definition.js +44 -1
  63. package/lib/metadataTypes/definitions/DataExtension.definition.js +4 -0
  64. package/lib/metadataTypes/definitions/DataExtensionTemplate.definition.js +6 -0
  65. package/lib/metadataTypes/definitions/DataExtract.definition.js +18 -14
  66. package/lib/metadataTypes/definitions/Discovery.definition.js +12 -0
  67. package/lib/metadataTypes/definitions/EmailSendDefinition.definition.js +4 -0
  68. package/lib/metadataTypes/definitions/EventDefinition.definition.js +22 -0
  69. package/lib/metadataTypes/definitions/FileTransfer.definition.js +4 -0
  70. package/lib/metadataTypes/definitions/Filter.definition.js +4 -0
  71. package/lib/metadataTypes/definitions/Folder.definition.js +6 -0
  72. package/lib/metadataTypes/definitions/FtpLocation.definition.js +4 -0
  73. package/lib/metadataTypes/definitions/ImportFile.definition.js +10 -5
  74. package/lib/metadataTypes/definitions/Interaction.definition.js +4 -0
  75. package/lib/metadataTypes/definitions/MobileCode.definition.js +163 -0
  76. package/lib/metadataTypes/definitions/MobileKeyword.definition.js +253 -0
  77. package/lib/metadataTypes/definitions/Query.definition.js +4 -0
  78. package/lib/metadataTypes/definitions/Role.definition.js +5 -0
  79. package/lib/metadataTypes/definitions/Script.definition.js +4 -0
  80. package/lib/metadataTypes/definitions/SetDefinition.definition.js +28 -0
  81. package/lib/metadataTypes/definitions/TriggeredSendDefinition.definition.js +4 -0
  82. package/lib/retrieveChangelog.js +7 -6
  83. package/lib/util/auth.js +117 -0
  84. package/lib/util/businessUnit.js +55 -66
  85. package/lib/util/cache.js +194 -0
  86. package/lib/util/cli.js +90 -116
  87. package/lib/util/config.js +302 -0
  88. package/lib/util/devops.js +240 -50
  89. package/lib/util/file.js +120 -191
  90. package/lib/util/init.config.js +195 -69
  91. package/lib/util/init.git.js +45 -50
  92. package/lib/util/init.js +72 -59
  93. package/lib/util/init.npm.js +48 -39
  94. package/lib/util/util.js +280 -564
  95. package/package.json +44 -33
  96. package/test/dataExtension.test.js +152 -0
  97. package/test/mockRoot/.mcdev-auth.json +8 -0
  98. package/test/mockRoot/.mcdevrc.json +67 -0
  99. package/test/mockRoot/deploy/testInstance/testBU/dataExtension/childBU_dataextension_test.dataExtension-meta.json +39 -0
  100. package/test/mockRoot/deploy/testInstance/testBU/dataExtension/testDataExtension.dataExtension-meta.json +23 -0
  101. package/test/mockRoot/deploy/testInstance/testBU/query/testExistingQuery.query-meta.json +11 -0
  102. package/test/mockRoot/deploy/testInstance/testBU/query/testExistingQuery.query-meta.sql +4 -0
  103. package/test/mockRoot/deploy/testInstance/testBU/query/testQuery.query-meta.json +11 -0
  104. package/test/mockRoot/deploy/testInstance/testBU/query/testQuery.query-meta.sql +4 -0
  105. package/test/query.test.js +149 -0
  106. package/test/resourceFactory.js +142 -0
  107. package/test/resources/1111111/dataFolder/retrieve-response.xml +43 -0
  108. package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/patch-response.json +18 -0
  109. package/test/resources/9999999/automation/v1/queries/get-response.json +24 -0
  110. package/test/resources/9999999/automation/v1/queries/post-response.json +18 -0
  111. package/test/resources/9999999/dataExtension/build-expected.json +51 -0
  112. package/test/resources/9999999/dataExtension/create-expected.json +23 -0
  113. package/test/resources/9999999/dataExtension/create-response.xml +54 -0
  114. package/test/resources/9999999/dataExtension/retrieve-expected.json +51 -0
  115. package/test/resources/9999999/dataExtension/retrieve-response.xml +47 -0
  116. package/test/resources/9999999/dataExtension/template-expected.json +51 -0
  117. package/test/resources/9999999/dataExtension/update-expected.json +55 -0
  118. package/test/resources/9999999/dataExtension/update-response.xml +52 -0
  119. package/test/resources/9999999/dataExtensionField/retrieve-response.xml +93 -0
  120. package/test/resources/9999999/dataExtensionTemplate/retrieve-response.xml +303 -0
  121. package/test/resources/9999999/dataFolder/retrieve-response.xml +65 -0
  122. package/test/resources/9999999/query/build-expected.json +8 -0
  123. package/test/resources/9999999/query/get-expected.json +11 -0
  124. package/test/resources/9999999/query/patch-expected.json +11 -0
  125. package/test/resources/9999999/query/post-expected.json +11 -0
  126. package/test/resources/9999999/query/template-expected.json +8 -0
  127. package/test/resources/auth.json +32 -0
  128. package/test/resources/rest404-response.json +5 -0
  129. package/test/resources/retrieve-response.xml +21 -0
  130. package/test/utils.js +107 -0
  131. package/types/mcdev.d.js +301 -0
  132. package/CHANGELOG.md +0 -126
  133. package/PULL_REQUEST_TEMPLATE.md +0 -19
  134. package/test/util/file.js +0 -51
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcdev",
3
- "version": "3.1.3",
3
+ "version": "4.0.0",
4
4
  "description": "Accenture Salesforce Marketing Cloud DevTools",
5
5
  "author": "joern.berkefeld, douglas.midgley, robert.zimmermann, maciej.barnas",
6
6
  "license": "MIT",
@@ -25,53 +25,64 @@
25
25
  "node": ">=14.16"
26
26
  },
27
27
  "scripts": {
28
- "start": "node lib/index.js",
29
- "mcdev": "node lib/index.js",
30
- "build": "run-s lint docs",
31
- "debug": "node --nolazy --inspect-brk=9229 lib/index.js",
32
- "docs": "jsdoc2md --files lib/**/*.js > docs/dist/documentation.md",
33
- "lint": "eslint --fix lib/**/*.js && eslint --fix test/**/*.js && prettier --write lib/**/*.js",
34
- "test": "mocha --recursive",
28
+ "start": "node lib/cli.js",
29
+ "mcdev": "node lib/cli.js",
30
+ "build": "run-s lint:fix docs test",
31
+ "debug": "node --nolazy --inspect-brk=9229 lib/cli.js",
32
+ "docs": "jsdoc2md --files lib/**/*.js types/**/*.js > docs/dist/documentation.md",
33
+ "lint:fix": "eslint --fix lib/**/*.js && eslint --fix types/*.js && eslint --fix test/**/*.js",
34
+ "lint": "run-p -c lint-type lint-lib lint-test",
35
+ "lint-lib": "eslint lib/**/*.js",
36
+ "lint-type": "eslint types/*.js",
37
+ "lint-test": "eslint test/**/*.js",
35
38
  "upgrade": "npm-check --update",
36
- "prepare": "husky install"
39
+ "prepare": "husky install",
40
+ "test": "mocha"
37
41
  },
38
42
  "dependencies": {
39
- "bluebird": "3.7.2",
40
- "cli-progress": "3.10.0",
43
+ "cli-progress": "3.11.2",
41
44
  "command-exists": "1.2.9",
45
+ "conf": "10.1.2",
42
46
  "console.table": "0.10.0",
43
- "fs-extra": "10.0.0",
44
- "inquirer": "8.2.0",
47
+ "deep-equal": "2.0.5",
48
+ "fs-extra": "10.1.0",
49
+ "inquirer": "8.2.2",
45
50
  "json-to-table": "4.2.1",
46
51
  "mustache": "4.2.0",
47
- "prettier": "2.5.1",
48
- "semver": "7.3.5",
49
- "sfmc-fuelsdk-node": "2.4.0",
50
- "simple-git": "2.48.0",
51
- "sql-formatter-plus": "1.3.6",
52
+ "p-limit": "3.1.0",
53
+ "prettier": "2.7.1",
54
+ "prettier-plugin-sql": "0.8.3",
55
+ "semver": "7.3.7",
56
+ "sfmc-sdk": "0.6.1",
57
+ "simple-git": "3.10.0",
52
58
  "toposort": "2.0.2",
53
- "update-notifier-git": "5.0.3",
54
- "winston": "3.3.4",
55
- "yargs": "17.3.0"
59
+ "update-notifier": "5.1.0",
60
+ "winston": "3.8.1",
61
+ "yargs": "17.5.1"
56
62
  },
57
63
  "devDependencies": {
58
- "chai": "4.3.4",
59
- "eslint": "8.4.1",
60
- "eslint-config-prettier": "8.3.0",
64
+ "assert": "2.0.0",
65
+ "axios-mock-adapter": "1.21.1",
66
+ "chai": "4.3.6",
67
+ "eslint": "8.19.0",
68
+ "eslint-config-prettier": "8.5.0",
61
69
  "eslint-config-ssjs": "1.1.11",
62
- "eslint-plugin-mocha": "10.0.1",
63
- "eslint-plugin-prettier": "4.0.0",
64
- "husky": "7.0.4",
65
- "jsdoc-to-markdown": "7.1.0",
66
- "lint-staged": "12.1.2",
67
- "mocha": "9.1.3",
70
+ "eslint-plugin-jsdoc": "39.3.3",
71
+ "eslint-plugin-mocha": "10.0.5",
72
+ "eslint-plugin-prettier": "4.2.1",
73
+ "eslint-plugin-unicorn": "43.0.0",
74
+ "husky": "8.0.1",
75
+ "jsdoc-to-markdown": "7.1.1",
76
+ "lint-staged": "13.0.3",
77
+ "mocha": "10.0.0",
78
+ "mock-fs": "5.1.2",
68
79
  "npm-check": "5.9.2",
69
- "npm-run-all": "4.1.5"
80
+ "npm-run-all": "4.1.5",
81
+ "prettier-eslint": "15.0.1"
70
82
  },
71
83
  "lint-staged": {
72
84
  "*.{js,jsx,ts,tsx}": [
73
- "eslint --fix",
74
- "prettier --write"
85
+ "eslint --fix"
75
86
  ]
76
87
  }
77
88
  }
@@ -0,0 +1,152 @@
1
+ const assert = require('chai').assert;
2
+ const cache = require('../lib/util/cache');
3
+ const testUtils = require('./utils');
4
+ const handler = require('../lib/index');
5
+
6
+ describe('dataExtension', () => {
7
+ beforeEach(() => {
8
+ testUtils.mockSetup();
9
+ });
10
+ afterEach(() => {
11
+ testUtils.mockReset();
12
+ });
13
+ describe('Retrieve ================', () => {
14
+ it('Should retrieve a data extension', async () => {
15
+ // WHEN
16
+ await handler.retrieve('testInstance/testBU', ['dataExtension']);
17
+ // THEN
18
+ // get results from cache
19
+ const result = cache.getCache();
20
+ assert.equal(
21
+ result.dataExtension ? Object.keys(result.dataExtension).length : 0,
22
+ 1,
23
+ 'only one dataExtension expected'
24
+ );
25
+ assert.deepEqual(
26
+ await testUtils.getActualFile('childBU_dataextension_test', 'dataExtension'),
27
+ await testUtils.getExpectedFile('9999999', 'dataExtension', 'retrieve'),
28
+
29
+ 'returned metadata was not equal expected'
30
+ );
31
+ assert.equal(
32
+ Object.values(testUtils.getAPIHistory()).flat().length,
33
+ 6,
34
+ 'Unexpected number of requests made'
35
+ );
36
+ return;
37
+ });
38
+ });
39
+ describe('Deploy ================', () => {
40
+ it('Should create & upsert a data extension', async () => {
41
+ // WHEN
42
+ await handler.deploy('testInstance/testBU', ['dataExtension']);
43
+ // THEN
44
+
45
+ // get results from cache
46
+ const result = cache.getCache();
47
+ assert.equal(
48
+ result.dataExtension ? Object.keys(result.dataExtension).length : 0,
49
+ 2,
50
+ 'two data extensions expected'
51
+ );
52
+ assert.deepEqual(
53
+ await testUtils.getActualFile('testDataExtension', 'dataExtension'),
54
+ await testUtils.getExpectedFile('9999999', 'dataExtension', 'create'),
55
+ 'returned metadata was not equal expected for create'
56
+ );
57
+ assert.deepEqual(
58
+ await testUtils.getActualFile('childBU_dataextension_test', 'dataExtension'),
59
+ await testUtils.getExpectedFile('9999999', 'dataExtension', 'update'),
60
+ 'returned metadata was not equal expected for update'
61
+ );
62
+ assert.equal(
63
+ Object.values(testUtils.getAPIHistory()).flat().length,
64
+ 11,
65
+ 'Unexpected number of requests made'
66
+ );
67
+ return;
68
+ });
69
+ });
70
+ describe('Templating ================', () => {
71
+ it('Should create a dataExtension template via retrieveAsTemplate and build it', async () => {
72
+ // GIVEN there is a template
73
+ const result = await handler.retrieveAsTemplate(
74
+ 'testInstance/testBU',
75
+ 'dataExtension',
76
+ ['childBU_dataextension_test'],
77
+ 'testMarket'
78
+ );
79
+
80
+ // WHEN
81
+ assert.equal(
82
+ result.dataExtension ? Object.keys(result.dataExtension).length : 0,
83
+ 1,
84
+ 'only one dataExtension expected'
85
+ );
86
+ assert.deepEqual(
87
+ await testUtils.getActualTemplate('childBU_dataextension_test', 'dataExtension'),
88
+ await testUtils.getExpectedFile('9999999', 'dataExtension', 'template'),
89
+ 'returned template was not equal expected'
90
+ );
91
+ // THEN
92
+ await handler.buildDefinition(
93
+ 'testInstance/testBU',
94
+ 'dataExtension',
95
+ 'childBU_dataextension_test',
96
+ 'testMarket'
97
+ );
98
+ assert.deepEqual(
99
+ await testUtils.getActualDeployFile('childBU_dataextension_test', 'dataExtension'),
100
+ await testUtils.getExpectedFile('9999999', 'dataExtension', 'build'),
101
+ 'returned deployment file was not equal expected'
102
+ );
103
+ assert.equal(
104
+ Object.values(testUtils.getAPIHistory()).flat().length,
105
+ 5,
106
+ 'Unexpected number of requests made'
107
+ );
108
+ return;
109
+ });
110
+ it('Should create a dataExtension template via buildTemplate and build it', async () => {
111
+ // download first before we test buildTemplate
112
+ await handler.retrieve('testInstance/testBU', ['dataExtension']);
113
+ // GIVEN there is a template
114
+ const result = await handler.buildTemplate(
115
+ 'testInstance/testBU',
116
+ 'dataExtension',
117
+ ['childBU_dataextension_test'],
118
+ 'testMarket'
119
+ );
120
+ // WHEN
121
+ assert.equal(
122
+ result.dataExtension ? Object.keys(result.dataExtension).length : 0,
123
+ 1,
124
+ 'only one dataExtension expected'
125
+ );
126
+ assert.deepEqual(
127
+ await testUtils.getActualTemplate('childBU_dataextension_test', 'dataExtension'),
128
+ await testUtils.getExpectedFile('9999999', 'dataExtension', 'template'),
129
+ 'returned template was not equal expected'
130
+ );
131
+ // THEN
132
+ await handler.buildDefinition(
133
+ 'testInstance/testBU',
134
+ 'dataExtension',
135
+ 'childBU_dataextension_test',
136
+ 'testMarket'
137
+ );
138
+
139
+ assert.deepEqual(
140
+ await testUtils.getActualDeployFile('childBU_dataextension_test', 'dataExtension'),
141
+ await testUtils.getExpectedFile('9999999', 'dataExtension', 'build'),
142
+ 'returned deployment file was not equal expected'
143
+ );
144
+ assert.equal(
145
+ Object.values(testUtils.getAPIHistory()).flat().length,
146
+ 5,
147
+ 'Unexpected number of requests made'
148
+ );
149
+ return;
150
+ });
151
+ });
152
+ });
@@ -0,0 +1,8 @@
1
+ {
2
+ "testInstance": {
3
+ "client_id": "71fzp43cyb1aksgflc159xxx",
4
+ "client_secret": "oDZE354QsMXzcFqKQlGgDxxx",
5
+ "auth_url": "https://mct0l7nxfq2r988t1kxfy8sc4xxx.auth.marketingcloudapis.com/",
6
+ "account_id": 1111111
7
+ }
8
+ }
@@ -0,0 +1,67 @@
1
+ {
2
+ "credentials": {
3
+ "testInstance": {
4
+ "eid": 1111111,
5
+ "businessUnits": {
6
+ "_ParentBU_": 1111111,
7
+ "testBU": 9999999
8
+ }
9
+ }
10
+ },
11
+ "options": {
12
+ "deployment": {
13
+ "commitHistory": 10,
14
+ "sourceTargetMapping": {
15
+ "deployment-source": "deployment-target"
16
+ },
17
+ "targetBranchBuMapping": {
18
+ "release/*": "MySandbox/QA-DE",
19
+ "master": ["MyProduction/PROD-DE", "MyProduction/PROD-NL"]
20
+ }
21
+ },
22
+ "documentType": "md",
23
+ "exclude": {},
24
+ "include": {},
25
+ "serverTimeOffset": -6,
26
+ "documentStandardRoles": false
27
+ },
28
+ "directories": {
29
+ "businessUnits": "businessUnits/",
30
+ "deploy": "deploy/",
31
+ "docs": "docs/",
32
+ "retrieve": "retrieve/",
33
+ "template": "template/",
34
+ "templateBuilds": ["retrieve/", "deploy/"]
35
+ },
36
+ "markets": {
37
+ "testMarket": {
38
+ "mid": "9999999",
39
+ "buName": "testBU",
40
+ "sharedFolder": "/Shared Data Extensions/test",
41
+ "suffix": "_test",
42
+ "countryCodeIn": "'test'"
43
+ }
44
+ },
45
+ "marketList": {},
46
+ "metaDataTypes": {
47
+ "documentOnRetrieve": ["accountUser", "automation", "dataExtension", "role"],
48
+ "retrieve": [
49
+ "asset",
50
+ "automation",
51
+ "dataExtension",
52
+ "dataExtract",
53
+ "emailSendDefinition",
54
+ "fileTransfer",
55
+ "ftpLocation",
56
+ "importFile",
57
+ "list",
58
+ "mobileCode",
59
+ "mobileKeyword",
60
+ "query",
61
+ "role",
62
+ "script",
63
+ "triggeredSendDefinition"
64
+ ]
65
+ },
66
+ "version": "4.0.0"
67
+ }
@@ -0,0 +1,39 @@
1
+ {
2
+ "CustomerKey": "childBU_dataextension_test",
3
+ "Name": "childBU_dataextension_test",
4
+ "Description": "",
5
+ "IsSendable": false,
6
+ "IsTestable": false,
7
+ "RowBasedRetention": true,
8
+ "ResetRetentionPeriodOnImport": false,
9
+ "DeleteAtEndOfRetentionPeriod": false,
10
+ "RetainUntil": "",
11
+ "Fields": [
12
+ {
13
+ "Name": "testField",
14
+ "DefaultValue": "",
15
+ "MaxLength": 254,
16
+ "IsRequired": true,
17
+ "IsPrimaryKey": false,
18
+ "FieldType": "Text"
19
+ },
20
+ {
21
+ "Name": "LastName",
22
+ "DefaultValue": "",
23
+ "MaxLength": 55,
24
+ "IsRequired": true,
25
+ "IsPrimaryKey": false,
26
+ "FieldType": "Text"
27
+ },
28
+ {
29
+ "Name": "ContactKey",
30
+ "DefaultValue": "",
31
+ "MaxLength": 40,
32
+ "IsRequired": true,
33
+ "IsPrimaryKey": true,
34
+ "FieldType": "Text"
35
+ }
36
+ ],
37
+ "r__folder_ContentType": "dataextension",
38
+ "r__folder_Path": "Data Extensions"
39
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "CustomerKey": "testDataExtension",
3
+ "Name": "testDataExtension",
4
+ "Description": "",
5
+ "IsSendable": false,
6
+ "IsTestable": false,
7
+ "RowBasedRetention": false,
8
+ "ResetRetentionPeriodOnImport": false,
9
+ "DeleteAtEndOfRetentionPeriod": false,
10
+ "RetainUntil": "",
11
+ "Fields": [
12
+ {
13
+ "Name": "testField",
14
+ "DefaultValue": "",
15
+ "MaxLength": 254,
16
+ "IsRequired": true,
17
+ "IsPrimaryKey": false,
18
+ "FieldType": "Text"
19
+ }
20
+ ],
21
+ "r__folder_ContentType": "dataextension",
22
+ "r__folder_Path": "Data Extensions"
23
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "testExistingQuery",
3
+ "key": "testExistingQuery",
4
+ "description": "updated",
5
+ "targetKey": "childBU_dataextension_test",
6
+ "createdDate": "2022-04-26T15:21:16.453",
7
+ "modifiedDate": "2022-04-26T16:04:15.88",
8
+ "targetUpdateTypeName": "Overwrite",
9
+ "isFrozen": false,
10
+ "r__folder_Path": "Query"
11
+ }
@@ -0,0 +1,4 @@
1
+ SELECT
2
+ SubscriberKey as testField
3
+ FROM
4
+ _Subscribers
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "testQuery",
3
+ "key": "testQuery",
4
+ "description": "",
5
+ "targetKey": "childBU_dataextension_test",
6
+ "createdDate": "2022-04-26T15:21:16.453",
7
+ "modifiedDate": "2022-04-26T16:04:15.88",
8
+ "targetUpdateTypeName": "Overwrite",
9
+ "isFrozen": false,
10
+ "r__folder_Path": "Query"
11
+ }
@@ -0,0 +1,4 @@
1
+ SELECT
2
+ SubscriberKey as testField
3
+ FROM
4
+ _Subscribers
@@ -0,0 +1,149 @@
1
+ const assert = require('chai').assert;
2
+ const cache = require('../lib/util/cache');
3
+ const testUtils = require('./utils');
4
+ const handler = require('../lib/index');
5
+
6
+ describe('query', () => {
7
+ beforeEach(() => {
8
+ testUtils.mockSetup();
9
+ });
10
+ afterEach(() => {
11
+ testUtils.mockReset();
12
+ });
13
+
14
+ describe('Retrieve ================', () => {
15
+ it('Should retrieve a query', async () => {
16
+ // WHEN
17
+ await handler.retrieve('testInstance/testBU', ['query']);
18
+ // THEN
19
+ // get results from cache
20
+ const result = cache.getCache();
21
+ assert.equal(
22
+ result.query ? Object.keys(result.query).length : 0,
23
+ 1,
24
+ 'only one query expected'
25
+ );
26
+ assert.deepEqual(
27
+ await testUtils.getActualFile('testExistingQuery', 'query'),
28
+ await testUtils.getExpectedFile('9999999', 'query', 'get'),
29
+ 'returned metadata was not equal expected'
30
+ );
31
+ assert.equal(
32
+ Object.values(testUtils.getAPIHistory()).flat().length,
33
+ 6,
34
+ 'Unexpected number of requests made'
35
+ );
36
+ return;
37
+ });
38
+ });
39
+ describe('Deploy ================', () => {
40
+ it('Should create & upsert a query', async () => {
41
+ // WHEN
42
+ await handler.deploy('testInstance/testBU', ['query']);
43
+ // THEN
44
+ // get results from cache
45
+ const result = cache.getCache();
46
+ assert.equal(
47
+ result.query ? Object.keys(result.query).length : 0,
48
+ 2,
49
+ 'two querys expected'
50
+ );
51
+ assert.deepEqual(
52
+ await testUtils.getActualFile('testQuery', 'query'),
53
+ await testUtils.getExpectedFile('9999999', 'query', 'post'),
54
+ 'returned metadata was not equal expected for insert query'
55
+ );
56
+ assert.deepEqual(
57
+ await testUtils.getActualFile('testExistingQuery', 'query'),
58
+ await testUtils.getExpectedFile('9999999', 'query', 'patch'),
59
+ 'returned metadata was not equal expected for insert query'
60
+ );
61
+ assert.equal(
62
+ Object.values(testUtils.getAPIHistory()).flat().length,
63
+ 8,
64
+ 'Unexpected number of requests made'
65
+ );
66
+ return;
67
+ });
68
+ });
69
+ describe('Templating ================', () => {
70
+ it('Should create a query template via retrieveAsTemplate and build it', async () => {
71
+ // GIVEN there is a template
72
+ const result = await handler.retrieveAsTemplate(
73
+ 'testInstance/testBU',
74
+ 'query',
75
+ ['testExistingQuery'],
76
+ 'testMarket'
77
+ );
78
+ // WHEN
79
+ assert.equal(
80
+ result.query ? Object.keys(result.query).length : 0,
81
+ 1,
82
+ 'only one query expected'
83
+ );
84
+ assert.deepEqual(
85
+ await testUtils.getActualTemplate('testExistingQuery', 'query'),
86
+ await testUtils.getExpectedFile('9999999', 'query', 'template'),
87
+ 'returned template was not equal expected'
88
+ );
89
+ // THEN
90
+ await handler.buildDefinition(
91
+ 'testInstance/testBU',
92
+ 'query',
93
+ 'testExistingQuery',
94
+ 'testMarket'
95
+ );
96
+ assert.deepEqual(
97
+ await testUtils.getActualDeployFile('testExistingQuery', 'query'),
98
+ await testUtils.getExpectedFile('9999999', 'query', 'build'),
99
+ 'returned deployment file was not equal expected'
100
+ );
101
+ assert.equal(
102
+ Object.values(testUtils.getAPIHistory()).flat().length,
103
+ 6,
104
+ 'Unexpected number of requests made'
105
+ );
106
+ return;
107
+ });
108
+ it('Should create a query template via buildTemplate and build it', async () => {
109
+ // download first before we test buildTemplate
110
+ await handler.retrieve('testInstance/testBU', ['query']);
111
+ // GIVEN there is a template
112
+ const result = await handler.buildTemplate(
113
+ 'testInstance/testBU',
114
+ 'query',
115
+ ['testExistingQuery'],
116
+ 'testMarket'
117
+ );
118
+ // WHEN
119
+ assert.equal(
120
+ result.query ? Object.keys(result.query).length : 0,
121
+ 1,
122
+ 'only one query expected'
123
+ );
124
+ assert.deepEqual(
125
+ await testUtils.getActualTemplate('testExistingQuery', 'query'),
126
+ await testUtils.getExpectedFile('9999999', 'query', 'template'),
127
+ 'returned template was not equal expected'
128
+ );
129
+ // THEN
130
+ await handler.buildDefinition(
131
+ 'testInstance/testBU',
132
+ 'query',
133
+ 'testExistingQuery',
134
+ 'testMarket'
135
+ );
136
+ assert.deepEqual(
137
+ await testUtils.getActualDeployFile('testExistingQuery', 'query'),
138
+ await testUtils.getExpectedFile('9999999', 'query', 'build'),
139
+ 'returned deployment file was not equal expected'
140
+ );
141
+ assert.equal(
142
+ Object.values(testUtils.getAPIHistory()).flat().length,
143
+ 6,
144
+ 'Unexpected number of requests made'
145
+ );
146
+ return;
147
+ });
148
+ });
149
+ });