From 47c75fb887f4b34f17eeb2402e95e3a62ad15edc Mon Sep 17 00:00:00 2001 From: i332371 Date: Mon, 29 Jul 2024 15:55:38 +0530 Subject: [PATCH 01/20] dev dependencies --- package.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/package.json b/package.json index 9421f3f..b3d79ed 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,12 @@ "express": "^4" }, "devDependencies": { + "@cap-js/audit-logging": "^0.8.0", + "@cap-js/change-tracking": "^1.0.6", + "@sap-cloud-sdk/connectivity": "^3.16.0", + "@sap-cloud-sdk/http-client": "^3.16.0", + "@sap-cloud-sdk/resilience": "^3.16.0", + "@sap-cloud-sdk/util": "^3.16.0", "@cap-js/sqlite": "^1.0.1", "@sap/ux-specification": "^1.108.4", "axios": "^1.4.0", From 23531c71aae5eef8337a9bced4a70e64684d1e6a Mon Sep 17 00:00:00 2001 From: i332371 Date: Thu, 3 Oct 2024 16:48:48 +0530 Subject: [PATCH 02/20] Test setup * Test files moved to test/ * test copy the needed files * some tests starts in own context (remote-service, messaging) --- .github/workflows/checkout | 58 +++++++++---------- package.json | 17 +++--- {xmpls => test}/audit-log.test.js | 16 ++++- {xmpls => test}/change-tracking.test.js | 14 ++++- .../messaging/test => test}/messaging.test.js | 10 ++-- .../test => test}/remote-service.test.js | 6 +- xmpls/messaging/app/fields.cds | 1 - xmpls/messaging/srv/mashup.cds | 4 ++ xmpls/remote-service/srv/mashup.cds | 4 ++ 9 files changed, 81 insertions(+), 49 deletions(-) rename {xmpls => test}/audit-log.test.js (84%) rename {xmpls => test}/change-tracking.test.js (94%) rename {xmpls/messaging/test => test}/messaging.test.js (96%) rename {xmpls/remote-service/test => test}/remote-service.test.js (95%) delete mode 100644 xmpls/messaging/app/fields.cds create mode 100644 xmpls/messaging/srv/mashup.cds create mode 100644 xmpls/remote-service/srv/mashup.cds diff --git a/.github/workflows/checkout b/.github/workflows/checkout index a591b78..6ba026b 100755 --- a/.github/workflows/checkout +++ b/.github/workflows/checkout @@ -2,41 +2,26 @@ /* eslint-disable no-console */ const [,,$1] = process.argv -const { exec } = require('child_process') -const path = require('path') +const { exec } = require('child_process'); const { readFile, writeFile } = require("fs").promises; const { join } = require("path"); +const levelUP = "../../" async function remoteService () { const TARGET_DIR = "xmpls/remote-service" - const levelUP = "../../" - const INCLUDES = ["srv", "test"] - const paths = INCLUDES.map(pattern => join(__dirname, levelUP, TARGET_DIR, pattern)) - const cmd = `cp -r ${paths.join(' ')} ${join(__dirname, levelUP)}` - await run(cmd); const packageJson = JSON.parse(await readFile(join(__dirname, levelUP ,"package.json"), "utf-8")); const delta = JSON.parse(await readFile(join(__dirname, levelUP, TARGET_DIR, "package.json"), "utf-8")); packageJson.cds.requires["API_BUSINESS_PARTNER"] = delta.cds.requires["API_BUSINESS_PARTNER"] await writeFile(join(__dirname, levelUP, "package.json"), JSON.stringify(packageJson, null, 2), "utf-8"); - // dependencies - const deps = [ - "@sap-cloud-sdk/connectivity", - "@sap-cloud-sdk/http-client", - "@sap-cloud-sdk/resilience", - "@sap-cloud-sdk/util" - ] - return await run(`npm add ${deps.join(" ")}`) + // Remove mashup.cds > needed only for test context + await run(`shx rm -rf ${join(__dirname, levelUP, TARGET_DIR, "srv/mashup.cds")}`); + } async function messaging () { const TARGET_DIR = "xmpls/messaging" - const levelUP = "../../" - const INCLUDES = ["app", "srv", "test"] - const paths = INCLUDES.map(pattern => join(__dirname, levelUP, TARGET_DIR, pattern)) - const cmd = `cp -r ${paths.join(' ')} ${join(__dirname, levelUP)}` - await run(cmd); const packageJson = JSON.parse(await readFile(join(__dirname, levelUP, "package.json"), "utf-8")); const delta = JSON.parse(await readFile(join(__dirname, levelUP, TARGET_DIR, "package.json"), "utf-8")); @@ -44,15 +29,26 @@ async function messaging () { packageJson.cds.requires["messaging"] = delta.cds.requires["messaging"] await writeFile(join(__dirname, levelUP, "package.json"), JSON.stringify(packageJson, null, 2), "utf-8"); - // dependencies - const deps = [ - "@sap-cloud-sdk/connectivity", - "@sap-cloud-sdk/http-client", - "@sap-cloud-sdk/resilience", - "@sap-cloud-sdk/util", - "@sap/xb-msg-amqp-v100" - ] - return await run(`npm add ${deps.join(" ")}`) + // Add UI fields for email in annotation + const content = "using from './incidents/field';" + await run(`shx echo '${content}' > ${join(__dirname, levelUP, TARGET_DIR, "app/fields.cds")}`); + + // Remove mashup.cds > needed only for test context + await run(`shx rm -rf ${join(__dirname, levelUP, TARGET_DIR, "srv/mashup.cds")}`); + +} + +async function setup (TARGET_DIR = 'xmpls', INCLUDES = []) { + const paths = INCLUDES.map(pattern => join(__dirname, levelUP, TARGET_DIR, pattern)) + const cmd = `shx cp -r ${paths.join(' ')} ${join(__dirname, levelUP, "srv")}` + await run(cmd); +} + +async function reset (TARGET_DIR = 'srv', INCLUDES = []) { + + const paths = INCLUDES.map(pattern => join(__dirname, levelUP, TARGET_DIR, pattern)) + const cmd = `shx rm -rf ${paths.join(' ')}` + await run(cmd); } function run (cmd, silent) { @@ -78,4 +74,6 @@ switch ($1) { break; default: console.log('Usage: ./checkout '); -} \ No newline at end of file +} + +module.exports = { setup, reset } \ No newline at end of file diff --git a/package.json b/package.json index b3d79ed..522c9f3 100644 --- a/package.json +++ b/package.json @@ -18,33 +18,32 @@ "devDependencies": { "@cap-js/audit-logging": "^0.8.0", "@cap-js/change-tracking": "^1.0.6", - "@sap-cloud-sdk/connectivity": "^3.16.0", - "@sap-cloud-sdk/http-client": "^3.16.0", - "@sap-cloud-sdk/resilience": "^3.16.0", - "@sap-cloud-sdk/util": "^3.16.0", "@cap-js/sqlite": "^1.0.1", "@sap/ux-specification": "^1.108.4", "axios": "^1.4.0", "chai": "^4.3.7", "chai-as-promised": "^7.1.1", - "chai-subset": "^1.6.0" + "chai-subset": "^1.6.0", + "shx": "^0.3.4" }, "scripts": { "watch": "cds watch", "start": "cds-serve", "test": "npx jest --silent", - "add-change-tracking": "npm add @cap-js/change-tracking && cp xmpls/change-tracking.cds ./srv && cp xmpls/change-tracking.test.js ./test", + "add-change-tracking": "npm add @cap-js/change-tracking && cp xmpls/change-tracking.cds ./srv", "add-telemetry": "npm add @cap-js/telemetry", "add-attachments": "npm add @cap-js/attachments && cp -r xmpls/attachments.cds ./db", "add-notifications": "npm add @cap-js/notifications && cp xmpls/alert-notifications.js ./srv && cp xmpls/notification-types.json ./srv", - "add-audit-log": "npm add @cap-js/audit-logging && cp xmpls/data-privacy.cds ./srv && cp xmpls/audit-log.test.js ./test", + "add-audit-log": "npm add @cap-js/audit-logging && cp xmpls/data-privacy.cds ./srv", "add-remote-service": "./.github/workflows/checkout remote-service", "add-messaging": "./.github/workflows/checkout messaging", "add-all-xmpls": "npm run add-remote-service && npm run add-messaging && npm run add-change-tracking && npm run add-audit-log", "reset": "read -p 'This will irreversibly reset your working directory including ALL files in this git repo. Continue?' -n 1 -r && echo && if [[ $REPLY =~ ^[Yy]$ ]]; then git clean -fd && git reset --hard && npm i; fi" }, "jest": { - "modulePathIgnorePatterns": ["/xmpls/"] + "modulePathIgnorePatterns": [ + "/xmpls/" + ] }, "sapux": [ "app/incidents" @@ -71,4 +70,4 @@ } }, "private": true -} +} \ No newline at end of file diff --git a/xmpls/audit-log.test.js b/test/audit-log.test.js similarity index 84% rename from xmpls/audit-log.test.js rename to test/audit-log.test.js index 3de685c..eb2a4cb 100644 --- a/xmpls/audit-log.test.js +++ b/test/audit-log.test.js @@ -1,10 +1,22 @@ const cds = require("@sap/cds"); -const { GET, POST, PATCH, DELETE, expect, axios, assert } = cds.test(__dirname + '/..', '--with-mocks') +const { setup, reset} = require("../.github/workflows/checkout"); + -axios.defaults.auth = { username: "alice" }; describe("Integration Test for AuditLog", () => { + + beforeAll(async () => { + await setup("xmpls", ["data-privacy.cds"]) + }) + + afterAll(async() => { + await reset("srv", ["data-privacy.cds"]) + }) + + const { GET, POST, PATCH, expect, axios, assert } = cds.test(__dirname + '/..', '--with-mocks') + let customerID,audit; beforeAll(async () => { + axios.defaults.auth = { username: "alice" }; audit = await cds.connect.to('audit-log') }); diff --git a/xmpls/change-tracking.test.js b/test/change-tracking.test.js similarity index 94% rename from xmpls/change-tracking.test.js rename to test/change-tracking.test.js index 89bf809..fe26271 100644 --- a/xmpls/change-tracking.test.js +++ b/test/change-tracking.test.js @@ -1,12 +1,24 @@ const cds = require("@sap/cds"); -const { GET, POST, PATCH, DELETE , expect, axios} = cds.test(__dirname + '/..', '--with-mocks') +const { setup, reset} = require("../.github/workflows/checkout"); describe("Integration Test for ChangeTracking", () => { + + beforeAll(async()=> { + await setup("xmpls", ["change-tracking.cds"]) + }) + + afterAll(async() => { + await reset("srv", ["change-tracking.cds"]) + }) + + const { GET, POST, PATCH, DELETE , expect, axios} = cds.test(__dirname + '/..', '--with-mocks') + let draftId,incidentId; axios.defaults.auth = { username: "alice" }; let processorService = null; let ChangeView = null; beforeAll(async () => { + processorService = await cds.connect.to('ProcessorService'); ChangeView = processorService.entities.ChangeView; }); diff --git a/xmpls/messaging/test/messaging.test.js b/test/messaging.test.js similarity index 96% rename from xmpls/messaging/test/messaging.test.js rename to test/messaging.test.js index 3e8dfb2..be1db32 100644 --- a/xmpls/messaging/test/messaging.test.js +++ b/test/messaging.test.js @@ -1,9 +1,11 @@ const cds = require("@sap/cds"); -const { GET, POST, PATCH, DELETE, expect, axios } = cds.test(__dirname + '/..', '--with-mocks') - describe("Integration Test for Eventing", () => { - let draftId,incidentId; - axios.defaults.auth = { username: "alice" }; + + const { GET, POST, PATCH, expect, axios } = cds.test(__dirname + '/../xmpls/messaging', '--with-mocks'); + + axios.defaults.auth = { username: "alice" }; + let draftId,incidentId; + describe("GET should return 200", () => { it("Should return list of Business Partners", async () => { diff --git a/xmpls/remote-service/test/remote-service.test.js b/test/remote-service.test.js similarity index 95% rename from xmpls/remote-service/test/remote-service.test.js rename to test/remote-service.test.js index e83fe42..21f5a23 100644 --- a/xmpls/remote-service/test/remote-service.test.js +++ b/test/remote-service.test.js @@ -1,8 +1,10 @@ const cds = require("@sap/cds"); -const { GET, POST, PATCH, DELETE, expect, axios } = cds.test(__dirname + '../../', '--with-mocks'); -axios.defaults.auth = { username: "alice" }; describe("Integration Test for Remote Service", () => { + + const { GET, POST, PATCH, expect, axios } = cds.test(__dirname + '/../xmpls/remote-service', '--with-mocks'); + + axios.defaults.auth = { username: "alice" }; let draftId,incidentId; describe("Test the BusinessPartner GET Endpoints", () => { diff --git a/xmpls/messaging/app/fields.cds b/xmpls/messaging/app/fields.cds deleted file mode 100644 index cdc5648..0000000 --- a/xmpls/messaging/app/fields.cds +++ /dev/null @@ -1 +0,0 @@ -using from './incidents/field'; \ No newline at end of file diff --git a/xmpls/messaging/srv/mashup.cds b/xmpls/messaging/srv/mashup.cds new file mode 100644 index 0000000..5cc44b0 --- /dev/null +++ b/xmpls/messaging/srv/mashup.cds @@ -0,0 +1,4 @@ +using { ProcessorService } from '../../../srv/services'; +using from '../../../srv/services'; +using from '../../../app/services'; +annotate ProcessorService with @impl: '../xmpls/messaging/srv/services.js'; diff --git a/xmpls/remote-service/srv/mashup.cds b/xmpls/remote-service/srv/mashup.cds new file mode 100644 index 0000000..e2199cd --- /dev/null +++ b/xmpls/remote-service/srv/mashup.cds @@ -0,0 +1,4 @@ +using { ProcessorService } from '../../../srv/services'; +using from '../../../srv/services'; +using from '../../../app/services'; +annotate ProcessorService with @impl: '../xmpls/remote-service/srv/services.js'; From ecd9601cf37b15a3dc853f0631251abc017a6aa2 Mon Sep 17 00:00:00 2001 From: i332371 Date: Thu, 3 Oct 2024 16:56:09 +0530 Subject: [PATCH 03/20] resolved conflicts --- package.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/package.json b/package.json index 32989fb..d098f59 100644 --- a/package.json +++ b/package.json @@ -16,17 +16,11 @@ "express": "^4" }, "devDependencies": { -<<<<<<< HEAD "@cap-js/audit-logging": "^0.8.0", "@cap-js/change-tracking": "^1.0.6", "@cap-js/sqlite": "^1.0.1", "@sap/ux-specification": "^1.108.4", "axios": "^1.4.0", -======= - "@cap-js/sqlite": "^1.7.3", - "@sap/ux-specification": "^1.120.16", - "axios": "^1.7.3", ->>>>>>> 043b1b4863fca62da1e2c284300ceeca8a1ed573 "chai": "^4.3.7", "chai-as-promised": "^7.1.1", "chai-subset": "^1.6.0", From f8becf0db1ad44113a31a5aeffdf13efa06ffffc Mon Sep 17 00:00:00 2001 From: i332371 Date: Thu, 3 Oct 2024 17:38:24 +0530 Subject: [PATCH 04/20] included attchments test --- package.json | 3 ++- {xmpls => test}/attachments.test.js | 16 +++++++++++++--- xmpls/attachments.cds | 2 +- 3 files changed, 16 insertions(+), 5 deletions(-) rename {xmpls => test}/attachments.test.js (90%) diff --git a/package.json b/package.json index d098f59..2ef75ec 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "devDependencies": { "@cap-js/audit-logging": "^0.8.0", "@cap-js/change-tracking": "^1.0.6", + "@cap-js/attachments": "^1.1.6", "@cap-js/sqlite": "^1.0.1", "@sap/ux-specification": "^1.108.4", "axios": "^1.4.0", @@ -32,7 +33,7 @@ "test": "npx jest --silent", "add-change-tracking": "npm add @cap-js/change-tracking && cp xmpls/change-tracking.cds ./srv", "add-telemetry": "npm add @cap-js/telemetry", - "add-attachments": "npm add @cap-js/attachments && cp -r xmpls/attachments.cds ./db && cp xmpls/attachments.test.js ./test", + "add-attachments": "npm add @cap-js/attachments && cp -r xmpls/attachments.cds ./srv", "add-notifications": "npm add @cap-js/notifications && cp xmpls/alert-notifications.js ./srv && cp xmpls/notification-types.json ./srv", "add-audit-log": "npm add @cap-js/audit-logging && cp xmpls/data-privacy.cds ./srv", "add-remote-service": "./.github/workflows/checkout remote-service", diff --git a/xmpls/attachments.test.js b/test/attachments.test.js similarity index 90% rename from xmpls/attachments.test.js rename to test/attachments.test.js index eec6b76..215244d 100644 --- a/xmpls/attachments.test.js +++ b/test/attachments.test.js @@ -1,11 +1,21 @@ const cds = require('@sap/cds') -const { GET, POST, PUT, DELETE , expect, axios} = cds.test(__dirname + '/..', '--with-mocks') +const { setup, reset} = require("../.github/workflows/checkout"); const { createReadStream } = cds.utils.fs; const { join } = cds.utils.path; -axios.defaults.auth = { username: 'alice' } jest.setTimeout(11111) +beforeAll(async()=> { + await setup("xmpls", ["attachments.cds"]) +}) + +afterAll(async() => { + await reset("srv", ["attachments.cds"]) +}) + +const { GET, POST, PUT, DELETE , expect, axios} = cds.test(__dirname + '/..', '--with-mocks') +axios.defaults.auth = { username: 'alice' } + describe('Test attachments service', () => { let draftId = null; let docId = null; @@ -39,7 +49,7 @@ describe('Test attachments service', () => { ) - const content = createReadStream(join(__dirname, "../xmpls/SolarPanelReport.pdf")); + const content = createReadStream(join(__dirname, "/../xmpls/SolarPanelReport.pdf")); const attachRes = await POST(`/odata/v4/processor/Incidents(ID=${draftId},IsActiveEntity=false)/attachments`, { up__ID: draftId, diff --git a/xmpls/attachments.cds b/xmpls/attachments.cds index f58acd5..e08e571 100644 --- a/xmpls/attachments.cds +++ b/xmpls/attachments.cds @@ -1,5 +1,5 @@ -using { sap.capire.incidents as my } from './schema'; +using { sap.capire.incidents as my } from '../db/schema'; using { Attachments } from '@cap-js/attachments'; extend my.Incidents with { From e7e82243ad4a8b78d3797b5360d0b88354b55030 Mon Sep 17 00:00:00 2001 From: i332371 Date: Wed, 23 Oct 2024 14:42:01 +0530 Subject: [PATCH 05/20] cds utils * Removed shx --- .github/workflows/checkout | 15 ++++++++------- package.json | 3 +-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/checkout b/.github/workflows/checkout index 6ba026b..d8ed0ea 100755 --- a/.github/workflows/checkout +++ b/.github/workflows/checkout @@ -6,6 +6,7 @@ const { exec } = require('child_process'); const { readFile, writeFile } = require("fs").promises; const { join } = require("path"); const levelUP = "../../" +const cds = require("@sap/cds") async function remoteService () { const TARGET_DIR = "xmpls/remote-service" @@ -16,7 +17,7 @@ async function remoteService () { await writeFile(join(__dirname, levelUP, "package.json"), JSON.stringify(packageJson, null, 2), "utf-8"); // Remove mashup.cds > needed only for test context - await run(`shx rm -rf ${join(__dirname, levelUP, TARGET_DIR, "srv/mashup.cds")}`); + await cds.utils.rm(join(__dirname, levelUP, TARGET_DIR, "srv/mashup.cds")); } @@ -31,24 +32,24 @@ async function messaging () { // Add UI fields for email in annotation const content = "using from './incidents/field';" - await run(`shx echo '${content}' > ${join(__dirname, levelUP, TARGET_DIR, "app/fields.cds")}`); + await run(`echo '${content}' > ${join(__dirname, levelUP, TARGET_DIR, "app/fields.cds")}`); // Remove mashup.cds > needed only for test context - await run(`shx rm -rf ${join(__dirname, levelUP, TARGET_DIR, "srv/mashup.cds")}`); + await cds.utils.rm(join(__dirname, levelUP, TARGET_DIR, "srv/mashup.cds")); } async function setup (TARGET_DIR = 'xmpls', INCLUDES = []) { const paths = INCLUDES.map(pattern => join(__dirname, levelUP, TARGET_DIR, pattern)) - const cmd = `shx cp -r ${paths.join(' ')} ${join(__dirname, levelUP, "srv")}` - await run(cmd); + for (let [index, srcPath] of paths.entries()) { + await cds.utils.copy(srcPath, join(__dirname, levelUP, "srv", INCLUDES[index])); + } } async function reset (TARGET_DIR = 'srv', INCLUDES = []) { const paths = INCLUDES.map(pattern => join(__dirname, levelUP, TARGET_DIR, pattern)) - const cmd = `shx rm -rf ${paths.join(' ')}` - await run(cmd); + await cds.utils.rm(paths.join(' ')) } function run (cmd, silent) { diff --git a/package.json b/package.json index 2ef75ec..80ea7b3 100644 --- a/package.json +++ b/package.json @@ -24,8 +24,7 @@ "axios": "^1.4.0", "chai": "^4.3.7", "chai-as-promised": "^7.1.1", - "chai-subset": "^1.6.0", - "shx": "^0.3.4" + "chai-subset": "^1.6.0" }, "scripts": { "watch": "cds watch", From 4433604e8ff172cd8949fc0e132b8ffe634dc914 Mon Sep 17 00:00:00 2001 From: Daniel Hutzel Date: Thu, 7 Nov 2024 10:20:50 +0100 Subject: [PATCH 06/20] Simplified by using copy and write from cds.utils --- .github/workflows/checkout | 100 +++------- test/attachments.test.js | 112 +++++------ test/audit-log.test.js | 105 +++++------ test/basics.test.js | 24 +-- test/change-tracking.test.js | 273 +++++++++++++-------------- test/drafts.test.js | 91 ++++----- test/messaging.test.js | 217 ++++++++++----------- test/remote-service.test.js | 170 ++++++++--------- xmpls/messaging/srv/mashup.cds | 35 +++- xmpls/messaging/srv/remote.cds | 30 --- xmpls/messaging/srv/services.js | 16 +- xmpls/remote-service/srv/mashup.cds | 33 +++- xmpls/remote-service/srv/remote.cds | 26 --- xmpls/remote-service/srv/services.js | 10 +- 14 files changed, 566 insertions(+), 676 deletions(-) delete mode 100644 xmpls/messaging/srv/remote.cds delete mode 100644 xmpls/remote-service/srv/remote.cds diff --git a/.github/workflows/checkout b/.github/workflows/checkout index d8ed0ea..ce42672 100755 --- a/.github/workflows/checkout +++ b/.github/workflows/checkout @@ -1,80 +1,32 @@ #!/usr/bin/env node /* eslint-disable no-console */ -const [,,$1] = process.argv -const { exec } = require('child_process'); -const { readFile, writeFile } = require("fs").promises; -const { join } = require("path"); -const levelUP = "../../" const cds = require("@sap/cds") - -async function remoteService () { - const TARGET_DIR = "xmpls/remote-service" - - const packageJson = JSON.parse(await readFile(join(__dirname, levelUP ,"package.json"), "utf-8")); - const delta = JSON.parse(await readFile(join(__dirname, levelUP, TARGET_DIR, "package.json"), "utf-8")); - packageJson.cds.requires["API_BUSINESS_PARTNER"] = delta.cds.requires["API_BUSINESS_PARTNER"] - await writeFile(join(__dirname, levelUP, "package.json"), JSON.stringify(packageJson, null, 2), "utf-8"); - - // Remove mashup.cds > needed only for test context - await cds.utils.rm(join(__dirname, levelUP, TARGET_DIR, "srv/mashup.cds")); - -} - -async function messaging () { - const TARGET_DIR = "xmpls/messaging" - - const packageJson = JSON.parse(await readFile(join(__dirname, levelUP, "package.json"), "utf-8")); - const delta = JSON.parse(await readFile(join(__dirname, levelUP, TARGET_DIR, "package.json"), "utf-8")); - packageJson.cds.requires["API_BUSINESS_PARTNER"] = delta.cds.requires["API_BUSINESS_PARTNER"] - packageJson.cds.requires["messaging"] = delta.cds.requires["messaging"] - await writeFile(join(__dirname, levelUP, "package.json"), JSON.stringify(packageJson, null, 2), "utf-8"); - - // Add UI fields for email in annotation - const content = "using from './incidents/field';" - await run(`echo '${content}' > ${join(__dirname, levelUP, TARGET_DIR, "app/fields.cds")}`); - - // Remove mashup.cds > needed only for test context - await cds.utils.rm(join(__dirname, levelUP, TARGET_DIR, "srv/mashup.cds")); - +const { read, write, path } = cds.utils +const { promises:fs } = require("fs") +const _stringified = o => JSON.stringify(o,null,2) + +const checkout = { + + async 'remote-service' () { + const xmpls = await read ('xmpls/remote-service/package.json') + const base = await read ('package.json') + for (let each of ['API_BUSINESS_PARTNER']) + base.cds.requires[each] = xmpls.cds.requires[each] + await write (_stringified(base)).to('package.json') + }, + + async messaging () { + const xmpls = await read ('xmpls/messaging/package.json') + const base = await read ('package.json') + for (let each of ['API_BUSINESS_PARTNER','messaging']) + base.cds.requires[each] = xmpls.cds.requires[each] + await write (_stringified(base)).to('package.json') + await fs.appendFile (path.join(cds.root,'srv','services.cds'), ` + using from './incidents/field'; // Add UI fields for email in annotation + `) + } } -async function setup (TARGET_DIR = 'xmpls', INCLUDES = []) { - const paths = INCLUDES.map(pattern => join(__dirname, levelUP, TARGET_DIR, pattern)) - for (let [index, srcPath] of paths.entries()) { - await cds.utils.copy(srcPath, join(__dirname, levelUP, "srv", INCLUDES[index])); - } -} - -async function reset (TARGET_DIR = 'srv', INCLUDES = []) { - - const paths = INCLUDES.map(pattern => join(__dirname, levelUP, TARGET_DIR, pattern)) - await cds.utils.rm(paths.join(' ')) -} - -function run (cmd, silent) { - if (cmd.raw) return run (String.raw(...arguments)) - if (cmd.endsWith('--silent')) silent = cmd = cmd.slice(0,-9) - if (typeof cmd === 'string') cmd = new Promise ((done,failed) => { - const cp = exec (cmd, (e,stdout) => e ? failed(e) : done(stdout)) - if (!silent) { - cp.stdout.on ('data', d => process.stdout.write(d)) - cp.stderr.on ('data', d => process.stderr.write(d)) - } - }) - return cmd -} - -switch ($1) { - - case 'remote-service': - remoteService(); - break; - case 'messaging': - messaging(); - break; - default: - console.log('Usage: ./checkout '); -} - -module.exports = { setup, reset } \ No newline at end of file +const [,,$1] = process.argv +checkout[$1]?.() || console.log('Usage: ./checkout remote-service | messaging') diff --git a/test/attachments.test.js b/test/attachments.test.js index 215244d..bf50132 100644 --- a/test/attachments.test.js +++ b/test/attachments.test.js @@ -1,93 +1,73 @@ const cds = require('@sap/cds') -const { setup, reset} = require("../.github/workflows/checkout"); -const { createReadStream } = cds.utils.fs; -const { join } = cds.utils.path; -jest.setTimeout(11111) +describe('Test attachments service', () => { -beforeAll(async()=> { - await setup("xmpls", ["attachments.cds"]) -}) + const { copy, rm, exists, path } = cds.utils; cds.root = path.resolve(__dirname,'..') + beforeAll (()=> copy('xmpls/attachments.cds').to('srv/attachments.cds')) + afterAll (() => rm('srv/attachments.cds')) -afterAll(async() => { - await reset("srv", ["attachments.cds"]) -}) + it('should have the srv/attachments.cds file in place', () => { + expect(exists('srv/attachments.cds')).to.be.true + }) -const { GET, POST, PUT, DELETE , expect, axios} = cds.test(__dirname + '/..', '--with-mocks') -axios.defaults.auth = { username: 'alice' } + const { GET, POST, PUT, DELETE , expect, axios} = cds.test() + axios.defaults.auth = { username: 'alice' } -describe('Test attachments service', () => { - let draftId = null; - let docId = null; + const Incidents = '/odata/v4/processor/Incidents' + const edit = 'ProcessorService.draftEdit' + const activate = 'ProcessorService.draftActivate' + const active = 'IsActiveEntity=true' + const draft = 'IsActiveEntity=false' + let ID = null, id = null - it('Create an incident ', async () => { - const { status, statusText, data } = await POST(`/odata/v4/processor/Incidents`, { + it('should create a new incident ', async () => { + const { status, data } = await POST(`${Incidents}`, { title: 'Urgent attention required !', status_code: 'N' }) - draftId = data.ID expect(status).to.equal(201) - expect(statusText).to.equal('Created') + ID = `ID=${data.ID}` //> captures the newly created Incident's ID for subsequent use... }) - it('+ Activate the draft', async () => { - const response = await POST( - `/odata/v4/processor/Incidents(ID=${draftId},IsActiveEntity=false)/ProcessorService.draftActivate` - ) + it('should activate the draft', async () => { + const response = await POST `${Incidents}(${ID},${draft})/${activate}` expect(response.status).to.eql(201) - }) + it(`should edit the incident to add an attachment`, async () => { + await POST `${Incidents}(${ID},${active})/${edit}` - describe('Test the file upload', () => { - it(`Should Close the Incident-${draftId}`, async () => { - const { status } = await POST( - `/odata/v4/processor/Incidents(ID=${draftId},IsActiveEntity=true)/ProcessorService.draftEdit`, - { - PreserveChanges: true - } - ) - - - const content = createReadStream(join(__dirname, "/../xmpls/SolarPanelReport.pdf")); - const attachRes = await POST(`/odata/v4/processor/Incidents(ID=${draftId},IsActiveEntity=false)/attachments`, - { - up__ID: draftId, + // Add an attachment entry + const created = await POST (`${Incidents}(${ID},${draft})/attachments`, { + up__ID: ID, filename: "SolarPanelReport.pdf", mimeType: "application/pdf", status: "Clean", - createdAt: new Date(), - }, { headers: { 'Content-Type': 'application/json' } }); - - console.log(attachRes); - docId = attachRes.data.ID; - console.log("doc id"+docId); - // Upload the file content with PUT - const uploadResp = await PUT( - `/odata/v4/processor/Incidents_attachments(up__ID=${draftId},ID=${docId},IsActiveEntity=false)/content`, - content, - { headers: { 'Content-Type': 'application/pdf' } } - ); - expect(uploadResp.status).to.equal(204); - // add attachments here + }, { headers: { 'Content-Type': 'application/json' }}) + expect(created.status).to.equal(201) + id = `ID=${created.data.ID}` //> captures the newly created Attachments's ID for subsequent use... - - const response = await POST( - `/odata/v4/processor/Incidents(ID=${draftId},IsActiveEntity=false)/ProcessorService.draftActivate` - ) - expect(response.status).to.eql(200) - }) - + // Upload the file + const uploaded = await PUT (`${Incidents}_attachments(up__${ID},${id},${draft})/content`, + require('fs').createReadStream (cds.root+'/xmpls/SolarPanelReport.pdf'), + { headers: { 'Content-Type': 'application/pdf' }} + ) + expect(uploaded.status).to.equal(204) + // Activate the draft + const activated = await POST `${Incidents}(${ID},${draft})/${activate}` + expect(activated.status).to.eql(200) }) - it('Check the uploaded file', async () => { - const response = await GET(`/odata/v4/processor/Incidents(ID=${draftId},IsActiveEntity=true)/attachments(up__ID=${draftId},ID=${docId},IsActiveEntity=true)/content`); - expect(response.status).to.equal(200); - expect(response.data).to.not.be.undefined; + + + it('should check the uploaded file', async () => { + const { status, data} = await GET `${Incidents}(${ID},${active})/attachments(up__${ID},${id})/content` + expect(status).to.equal(200) + expect(data).to.not.be.undefined }) - it('- Delete the Incident', async () => { - const response = await DELETE(`/odata/v4/processor/Incidents(ID=${draftId},IsActiveEntity=true)`) - expect(response.status).to.eql(204) + it('should delete the incident', async () => { + const { status } = await DELETE `${Incidents}(${ID},${active})` + expect(status).to.eql(204) }) }) diff --git a/test/audit-log.test.js b/test/audit-log.test.js index eb2a4cb..d0a3f84 100644 --- a/test/audit-log.test.js +++ b/test/audit-log.test.js @@ -1,74 +1,61 @@ -const cds = require("@sap/cds"); -const { setup, reset} = require("../.github/workflows/checkout"); +const cds = require("@sap/cds") +const e = require("express") describe("Integration Test for AuditLog", () => { - beforeAll(async () => { - await setup("xmpls", ["data-privacy.cds"]) - }) + const { copy, rm, exists, path } = cds.utils; cds.root = path.resolve(__dirname,'..') + beforeAll (()=> copy('xmpls/data-privacy.cds').to('srv/data-privacy.cds')) + afterAll (() => rm('srv/data-privacy.cds')) - afterAll(async() => { - await reset("srv", ["data-privacy.cds"]) + it('should have the srv/data-privacy.cds file in place', () => { + expect(exists('srv/data-privacy.cds')).to.be.true }) - - const { GET, POST, PATCH, expect, axios, assert } = cds.test(__dirname + '/..', '--with-mocks') - let customerID,audit; - beforeAll(async () => { - axios.defaults.auth = { username: "alice" }; - audit = await cds.connect.to('audit-log') - }); + const { GET, POST, PATCH , expect, axios} = cds.test() + axios.defaults.auth = { username: 'alice' } - it("Should return list of Customers", async () => { - const response = await GET("/odata/v4/processor/Customers"); - - audit.on('SensitiveDataRead', function (req) { - const { event, data } = req - assert.ok(event.includes("SensitiveDataRead")) - }) - expect(response.status).to.eql(200); - }); + let ID + let audit; beforeAll (async () => { + audit = await cds.connect.to('audit-log') + audit.on('PersonalDataModified', req => expect(req.event).to.include('PersonalDataModified')) + audit.on('SensitiveDataRead', req => expect(req.event).to.include("SensitiveDataRead")) + }) + it("Should return list of Customers", async () => { + const {status} = await GET `/odata/v4/processor/Customers` + expect(status).to.eql(200) + }) - it("Should return list of Customers data by explicitly selecting the fields", async () => { - const response = await GET("/odata/v4/processor/Customers?$select=name"); - expect(response.status).to.eql(200); - }); + it("Should return list of Customers data by explicitly selecting the fields", async () => { + const {status} = await GET `/odata/v4/processor/Customers?$select=name` + expect(status).to.eql(200) + }) - it('Creating a customer with personal data', async () => { - const response = await POST(`/odata/v4/admin/Customers`, { - ID: "{{$guid}}", - firstName: "Bob", - lastName: "Builder", - email: "bob.builder@example.com" - }); - audit.on('PersonalDataModified', function (req) { - const { event, data } = req - assert.ok(event.includes("PersonalDataModified")) - }) - customerID = response.data.ID; - expect(response.status).to.equal(201); - }); + it('Creating a customer with personal data', async () => { + const { status, data } = await POST (`/odata/v4/admin/Customers`, { + ID: "{{$guid}}", + firstName: "Bob", + lastName: "Builder", + email: "bob.builder@example.com" + }) + expect(status).to.equal(201) + ID = data.ID + }) - it('Updating a customer with personal data details', async () => { - const audit = await cds.connect.to('audit-log') - audit.on('PersonalDataModified', function (req) { - const { event, data } = req - assert.ok(event.includes("PersonalDataModified")) - }) - const response = await PATCH(`/odata/v4/admin/Customers('${customerID}')`, { - "addresses": [ - { - "city": "Walldorf", - "postCode": "69190", - "streetAddress": "Dietmar-Hopp-Allee 16" - } - ] - }); - expect(response.status).to.equal(200); - }); + it('Updating a customer with personal data details', async () => { + const {status} = await PATCH (`/odata/v4/admin/Customers('${ID}')`, { + "addresses": [ + { + "city": "Walldorf", + "postCode": "69190", + "streetAddress": "Dietmar-Hopp-Allee 16" + } + ] + }) + expect(status).to.equal(200) + }) -}); +}) diff --git a/test/basics.test.js b/test/basics.test.js index 99eaf63..52787da 100644 --- a/test/basics.test.js +++ b/test/basics.test.js @@ -1,23 +1,25 @@ -const cds = require('@sap/cds/lib') -const { GET, expect, axios } = cds.test(__dirname + '/..', '--with-mocks') - -axios.defaults.auth = { username: 'alice' } +const cds = require('@sap/cds') describe('Test The GET Endpoints', () => { + const { GET, expect, axios } = cds.test(__dirname+'/..') + axios.defaults.auth = { username: 'alice' } + it('Should check Processor Service', async () => { - const processorService = await cds.connect.to('ProcessorService') - const { Incidents } = processorService.entities - expect(await SELECT.from(Incidents)).to.have.length(4) + let srv = await cds.connect.to('ProcessorService') + let {Incidents} = srv.entities + let incidents = await SELECT.from(Incidents) + expect(incidents).to.have.length(4) }) it('Should check Customers', async () => { - const processorService = await cds.connect.to('ProcessorService') - const { Customers } = processorService.entities - expect(await SELECT.from(Customers)).to.have.length(3) + let srv = await cds.connect.to('ProcessorService') + let {Customers} = srv.entities + let customers = await SELECT.from(Customers) + expect(customers).to.have.length(3) }) it('Test Expand Entity Endpoint', async () => { - const { data } = await GET`/odata/v4/processor/Customers?$select=firstName&$expand=incidents` + let {data} = await GET `/odata/v4/processor/Customers?$select=firstName&$expand=incidents` expect(data).to.be.an('object') }) }) diff --git a/test/change-tracking.test.js b/test/change-tracking.test.js index fe26271..f6daee6 100644 --- a/test/change-tracking.test.js +++ b/test/change-tracking.test.js @@ -1,145 +1,140 @@ -const cds = require("@sap/cds"); -const { setup, reset} = require("../.github/workflows/checkout"); +const cds = require("@sap/cds") describe("Integration Test for ChangeTracking", () => { - beforeAll(async()=> { - await setup("xmpls", ["change-tracking.cds"]) + const { copy, rm, exists, path } = cds.utils; cds.root = path.resolve(__dirname,'..') + beforeAll (()=> copy('xmpls/change-tracking.cds').to('srv/change-tracking.cds')) + afterAll (() => rm('srv/change-tracking.cds')) + + it('should have the srv/change-tracking.cds file in place', () => { + expect(exists('srv/change-tracking.cds')).to.be.true + }) + + const { GET, POST, PATCH, DELETE, expect, axios} = cds.test() + axios.defaults.auth = { username: 'alice' } + + const Incidents = '/odata/v4/processor/Incidents' + const edit = 'ProcessorService.draftEdit' + const activate = 'ProcessorService.draftActivate' + const active = 'IsActiveEntity=true' + const draft = 'IsActiveEntity=false' + let ID = null, id = null + + let processorService = null + let ChangeView = null + + beforeAll(async () => { + processorService = await cds.connect.to('ProcessorService') + ChangeView = processorService.entities.ChangeView + }) + + it('Create an incident ', async () => { + const { status, data } = await POST (`${Incidents}`, { + title: 'Urgent attention required !', + status_code: 'N', + customer: { ID: '1004100' } + }) + expect(status).to.equal(201) + ID = `ID=${id=data.ID}` //> captures the newly created Incident's ID for subsequent use... + }) + + it('+ Activate the draft & check Urgency code as H using custom logic', async () => { + const response = await POST `${Incidents}(${ID},${draft})/${activate}` + expect(response.status).to.eql(201) + expect(response.data.urgency_code).to.eql('H') + }) + + it('+ Test the incident status', async () => { + const { status, data } = await GET `${Incidents}(${ID},${active})` + expect(status).to.eql(200) + expect(data.status_code).to.eql('N') + }) + + it('+ Test the title detail in ChangeView', async () => { + const changes = await SELECT.from(ChangeView).where({ + entity: "sap.capire.incidents.Incidents", + attribute: "title", + }) + expect(changes.length).to.equal(1) + const [change] = changes + expect(change.entityKey).to.equal(id) + expect(change.attribute).to.equal("title") + expect(change.modification).to.equal("create") + expect(change.valueChangedFrom).to.equal("") + expect(change.valueChangedTo).to.equal("Urgent attention required !") + }) + + it('+ Test the status detail in ChangeView', async () => { + const changes = await SELECT.from(ChangeView).where({ + entity: "sap.capire.incidents.Incidents", + attribute: "status", + }) + expect(changes.length).to.equal(1) + const [change] = changes + expect(change.entityKey).to.equal(id) + expect(change.attribute).to.equal("status") + expect(change.modification).to.equal("create") + expect(change.valueChangedFrom).to.equal("") + expect(change.valueChangedTo).to.equal("N") + }) + + it('+ Test the customer detail in ChangeView', async () => { + const changes = await SELECT.from(ChangeView).where({ + entity: "sap.capire.incidents.Incidents", + attribute: "customer", }) + expect(changes.length).to.equal(1) + const [change] = changes + expect(change.entityKey).to.equal(id) + expect(change.attribute).to.equal("customer") + expect(change.modification).to.equal("create") + expect(change.valueChangedFrom).to.equal("") + expect(change.valueChangedTo).to.equal("Sunny Sunshine") + }) - afterAll(async() => { - await reset("srv", ["change-tracking.cds"]) + describe("Test Changes for Update Incident", () => { + it(`Should Close the Incident-${id}`, async ()=>{ + const {status} = await POST `${Incidents}(${ID},${active})/${edit}` + expect(status).to.equal(201) + }) + it(`Should Close the Incident-${id}`, async ()=>{ + const {status} = await PATCH (`${Incidents}(${ID},${draft})`,{status_code: 'C'}) + expect(status).to.equal(200) + }) + it('+ Activate the draft & check Status code as C using custom logic', async () => { + const {status} = await POST `${Incidents}(${ID},${draft})/${activate}` + expect(status).to.eql(200) + }) + it('+ Test the status detail in ChangeView', async () => { + // await GET `${Incidents}?$filter=ID eq ${id}` + const changes = await SELECT.from(ChangeView).where({ + entity: "sap.capire.incidents.Incidents", + attribute: "status", + modification: 'update', + }) + expect(changes.length).to.equal(1) + const [change] = changes + expect(change.entityKey).to.equal(id) + expect(change.attribute).to.equal("status") + expect(change.modification).to.equal("update") + expect(change.valueChangedFrom).to.equal("N") + expect(change.valueChangedTo).to.equal("C") }) - - const { GET, POST, PATCH, DELETE , expect, axios} = cds.test(__dirname + '/..', '--with-mocks') - - let draftId,incidentId; - axios.defaults.auth = { username: "alice" }; - let processorService = null; - let ChangeView = null; - beforeAll(async () => { - - processorService = await cds.connect.to('ProcessorService'); - ChangeView = processorService.entities.ChangeView; - }); - it('Create an incident ', async () => { - const { status, statusText, data } = await POST(`/odata/v4/processor/Incidents`, { - title: 'Urgent attention required !', - status_code: 'N', - "customer": {ID:"1004100"} - }); - draftId = data.ID; - expect(status).to.equal(201); - expect(statusText).to.equal('Created'); - }); - - it('+ Activate the draft & check Urgency code as H using custom logic', async () => { - const response = await POST( - `/odata/v4/processor/Incidents(ID=${draftId},IsActiveEntity=false)/ProcessorService.draftActivate` - ); - expect(response.status).to.eql(201); - expect(response.data.urgency_code).to.eql('H'); - }); - - it('+ Test the incident status', async () => { - const { status, data: { status_code, ID } } = await GET(`/odata/v4/processor/Incidents(ID=${draftId},IsActiveEntity=true)`); - incidentId = ID; - expect(status).to.eql(200); - expect(status_code).to.eql('N'); - }); - - it('+ Test the title detail in ChangeView', async () => { - const response = await GET(`/odata/v4/processor/Incidents?$filter=ID eq ${draftId}`); - const incidentChanges = await SELECT.from(ChangeView).where({ - entity: "sap.capire.incidents.Incidents", - attribute: "title", - }) - expect(incidentChanges.length).to.equal(1); - const incidentChange = incidentChanges[0]; - expect(incidentChange.entityKey).to.equal(draftId); - expect(incidentChange.attribute).to.equal("title"); - expect(incidentChange.modification).to.equal("create"); - expect(incidentChange.valueChangedFrom).to.equal(""); - expect(incidentChange.valueChangedTo).to.equal("Urgent attention required !"); - }); - - it('+ Test the status detail in ChangeView', async () => { - const response = await GET(`/odata/v4/processor/Incidents?$filter=ID eq ${draftId}`); - const incidentChanges = await SELECT.from(ChangeView).where({ - entity: "sap.capire.incidents.Incidents", - attribute: "status", - }) - expect(incidentChanges.length).to.equal(1); - const incidentChange = incidentChanges[0]; - expect(incidentChange.entityKey).to.equal(draftId); - expect(incidentChange.attribute).to.equal("status"); - expect(incidentChange.modification).to.equal("create"); - expect(incidentChange.valueChangedFrom).to.equal(""); - expect(incidentChange.valueChangedTo).to.equal("N"); - }); - - it('+ Test the customer detail in ChangeView', async () => { - const response = await GET(`/odata/v4/processor/Incidents?$filter=ID eq ${draftId}`); - const incidentChanges = await SELECT.from(ChangeView).where({ - entity: "sap.capire.incidents.Incidents", - attribute: "customer", - }) - expect(incidentChanges.length).to.equal(1); - const incidentChange = incidentChanges[0]; - expect(incidentChange.entityKey).to.equal(draftId); - expect(incidentChange.attribute).to.equal("customer"); - expect(incidentChange.modification).to.equal("create"); - expect(incidentChange.valueChangedFrom).to.equal(""); - expect(incidentChange.valueChangedTo).to.equal("Sunny Sunshine"); - }); - - describe("Test Changes for Update Incident", () => { - it(`Should Close the Incident-${draftId}`, async ()=>{ - const {status} = await POST(`/odata/v4/processor/Incidents(ID=${draftId},IsActiveEntity=true)/ProcessorService.draftEdit`, - { - "PreserveChanges": true - }); - expect(status).to.equal(201); - }); - it(`Should Close the Incident-${draftId}`, async ()=>{ - const {status } = await PATCH(`/odata/v4/processor/Incidents(ID=${draftId},IsActiveEntity=false)`,{status_code: 'C'}); - expect(status).to.equal(200); - }); - it('+ Activate the draft & check Status code as C using custom logic', async () => { - const response = await POST( - `/odata/v4/processor/Incidents(ID=${draftId},IsActiveEntity=false)/ProcessorService.draftActivate` - ); - expect(response.status).to.eql(200); - }); - it('+ Test the status detail in ChangeView', async () => { - const response = await GET(`/odata/v4/processor/Incidents?$filter=ID eq ${draftId}`); - const incidentChanges = await SELECT.from(ChangeView).where({ - entity: "sap.capire.incidents.Incidents", - attribute: "status", - modification: 'update', - }) - expect(incidentChanges.length).to.equal(1); - const incidentChange = incidentChanges[0]; - expect(incidentChange.entityKey).to.equal(draftId); - expect(incidentChange.attribute).to.equal("status"); - expect(incidentChange.modification).to.equal("update"); - expect(incidentChange.valueChangedFrom).to.equal("N"); - expect(incidentChange.valueChangedTo).to.equal("C"); - }); - }); - - describe("Test Changes for Delete Incident", () => { - it('- Delete the Incident', async () => { - const response = await DELETE(`/odata/v4/processor/Incidents(ID=${draftId},IsActiveEntity=true)`); - expect(response.status).to.eql(204); - }); - - it('+ Test the status detail in ChangeView', async () => { - const incidentChanges = await SELECT.from(ChangeView).where({ - entity: "sap.capire.incidents.Incidents", - attribute: "status", - }) - expect(incidentChanges.length).to.equal(0); - }); - }); -}); + }) + + describe("Test Changes for Delete Incident", () => { + it('- Delete the Incident', async () => { + const {status} = await DELETE `${Incidents}(${ID},${active})` + expect(status).to.eql(204) + }) + + it('+ Test the status detail in ChangeView', async () => { + const changes = await SELECT.from(ChangeView).where({ + entity: "sap.capire.incidents.Incidents", + attribute: "status", + }) + expect(changes.length).to.equal(0) + }) + }) + +}) diff --git a/test/drafts.test.js b/test/drafts.test.js index 68dc32d..fa6c37c 100644 --- a/test/drafts.test.js +++ b/test/drafts.test.js @@ -1,94 +1,72 @@ -const cds = require('@sap/cds/lib') -const { GET, POST, DELETE, PATCH, expect, axios } = cds.test(__dirname + '/..', '--with-mocks') - -axios.defaults.auth = { username: 'alice' } +const cds = require('@sap/cds') describe('Draft Choreography APIs', () => { - let draftId, incidentId - it('Create a new incident', async () => { - const { status, statusText, data } = await POST(`/odata/v4/processor/Incidents`, { + const { GET, POST, DELETE, PATCH, expect, axios } = cds.test(__dirname+'/..') + axios.defaults.auth = { username: 'alice' } + + const Incidents = '/odata/v4/processor/Incidents' + const edit = 'ProcessorService.draftEdit' + const activate = 'ProcessorService.draftActivate' + const active = 'IsActiveEntity=true' + const draft = 'IsActiveEntity=false' + let ID + + it('should create a new incident', async () => { + const { status, data } = await POST (`${Incidents}`, { title: 'Urgent attention required !', status_code: 'N' }) - draftId = data.ID expect(status).to.equal(201) - expect(statusText).to.equal('Created') + ID = `ID=${data.ID}` //> captures the newly created Incident's ID for subsequent use... }) - it('Save the draft & check urgency code as H using custom logic', async () => { - const response = await POST( - `/odata/v4/processor/Incidents(ID=${draftId},IsActiveEntity=false)/ProcessorService.draftActivate` - ) - expect(response.status).to.eql(201) - expect(response.data.urgency_code).to.eql('H') + it('should save the draft & check urgency code as H using custom logic', async () => { + const { status, data } = await POST `${Incidents}(${ID},${draft})/${activate}` + expect(status).to.eql(201) + expect(data.urgency_code).to.eql('H') }) it ('should test the incident status', async () => { - const { - status, - data: { status_code, ID } - } = await GET(`/odata/v4/processor/Incidents(ID=${draftId},IsActiveEntity=true)`) - incidentId = ID + const { status, data } = await GET `${Incidents}(${ID},${active})` expect(status).to.eql(200) - expect(status_code).to.eql('N') + expect(data.status_code).to.eql('N') }) it ('should edit the incident again', async () => { - const { status } = await POST( - `/odata/v4/processor/Incidents(ID=${incidentId},IsActiveEntity=true)/ProcessorService.draftEdit`, - { - PreserveChanges: true - } - ) + const {status} = await POST `${Incidents}(${ID},${active})/${edit}` expect(status).to.equal(201) }) it (`should set status to closed`, async () => { - const { status } = await PATCH(`/odata/v4/processor/Incidents(ID=${incidentId},IsActiveEntity=false)`, { - status_code: 'C' - }) + const { status } = await PATCH (`${Incidents}(${ID},${draft})`, { status_code: 'C' }) expect(status).to.equal(200) }) it ('should save the draft & check status code as C using custom logic', async () => { - const response = await POST( - `/odata/v4/processor/Incidents(ID=${incidentId},IsActiveEntity=false)/ProcessorService.draftActivate` - ) - expect(response.status).to.eql(200) + const {status} = await POST `${Incidents}(${ID},${draft})/${activate}` + expect(status).to.eql(200) }) it ('should test the incident status to be closed', async () => { - const { - status, - data: { status_code } - } = await GET(`/odata/v4/processor/Incidents(ID=${incidentId},IsActiveEntity=true)`) + const { status, data } = await GET `${Incidents}(${ID},${active})` expect(status).to.eql(200) - expect(status_code).to.eql('C') + expect(data.status_code).to.eql('C') }) - it (`should re-open the closed incident-${draftId}`, async () => { - const { status } = await POST( - `/odata/v4/processor/Incidents(ID=${incidentId},IsActiveEntity=true)/ProcessorService.draftEdit`, - { - PreserveChanges: true - } - ) + it (`should re-open the closed incident-${ID}`, async () => { + const {status} = await POST `${Incidents}(${ID},${active})/${edit}` expect(status).to.equal(201) }) it (`should fail setting the status to 'N'`, async () => { - const { status } = await PATCH(`/odata/v4/processor/Incidents(ID=${incidentId},IsActiveEntity=false)`, { - status_code: 'N' - }) + const {status} = await PATCH (`${Incidents}(${ID},${draft})`, { status_code: 'N' }) expect(status).to.equal(200) }) it ('should fail to save drafts for closed incidents', async () => { try { - await POST( - `/odata/v4/processor/Incidents(ID=${incidentId},IsActiveEntity=false)/ProcessorService.draftActivate` - ) + await POST `${Incidents}(${ID},${draft})/${activate}` } catch (error) { expect(error.response.status).to.eql(500) expect(error.response.data.error.message).to.include(`Can't modify a closed incident`) @@ -96,12 +74,13 @@ describe('Draft Choreography APIs', () => { }) it ('should delete the Draft', async () => { - const response = await DELETE(`/odata/v4/processor/Incidents(ID=${draftId},IsActiveEntity=false)`) - expect(response.status).to.eql(204) + const {status} = await DELETE `${Incidents}(${ID},${draft})` + expect(status).to.eql(204) }) it ('should delete the Incident', async () => { - const response = await DELETE(`/odata/v4/processor/Incidents(ID=${draftId},IsActiveEntity=true)`) - expect(response.status).to.eql(204) + const {status} = await DELETE `${Incidents}(${ID},${active})` + expect(status).to.eql(204) }) + }) diff --git a/test/messaging.test.js b/test/messaging.test.js index be1db32..244cfea 100644 --- a/test/messaging.test.js +++ b/test/messaging.test.js @@ -1,108 +1,113 @@ -const cds = require("@sap/cds"); +const cds = require("@sap/cds") + describe("Integration Test for Eventing", () => { - const { GET, POST, PATCH, expect, axios } = cds.test(__dirname + '/../xmpls/messaging', '--with-mocks'); - - axios.defaults.auth = { username: "alice" }; - let draftId,incidentId; - - describe("GET should return 200", () => { - - it("Should return list of Business Partners", async () => { - const response = await GET("/odata/v4/api-business-partner/A_BusinessPartner"); - expect(response.status).to.eql(200); - }); - - it("Should return list of Business Partners Address", async () => { - const response = await GET("/odata/v4/api-business-partner/A_BusinessPartnerAddress"); - expect(response.status).to.eql(200); - }); - it("Should return list of Business Partners Email Address", async () => { - const response = await GET("/odata/v4/api-business-partner/A_AddressEmailAddress"); - expect(response.status).to.eql(200); - }); - it("Should return list of Business Partners Address PhoneNumber", async () => { - const response = await GET("/odata/v4/api-business-partner/A_AddressPhoneNumber"); - expect(response.status).to.eql(200); - }); - }); - - describe('Draft Choreography APIs', () => { - it('Create an incident ', async () => { - const { status, statusText, data } = await POST(`/odata/v4/processor/Incidents`, { - title: 'Urgent attention required !', - status_code: 'N', - "customer": {ID:"1004100"} - }); - draftId = data.ID; - expect(status).to.equal(201); - expect(statusText).to.equal('Created'); - }); - it('+ Activate the draft & check Urgency code as H using custom logic', async () => { - const response = await POST( - `/odata/v4/processor/Incidents(ID=${draftId},IsActiveEntity=false)/ProcessorService.draftActivate` - ); - expect(response.status).to.eql(201); - expect(response.data.urgency_code).to.eql('H'); - }); - it('+ Test the customer detail', async () => { - const response = await GET(`/odata/v4/processor/Incidents?$filter=ID eq ${draftId}`); - expect(response.status).to.eql(200); - expect(response.data.value).to.exist; - expect(response.data.value[0]).to.contains({ - "customer_ID": "1004100" - }); - incidentId = response.data.ID; - }); - - describe("Create annd Update Business Partner", () => { - it("Update Business Partner", async () => { - const response = await PATCH( - `/odata/v4/api-business-partner/A_BusinessPartner('1004100')`, - { - to_BusinessPartnerAddress: [{ - AddressID: "457", - to_EmailAddress:[{ - AddressID: "457", - Person: "johnson", - OrdinalNumber: "334", - EmailAddress: "sunny@test.com" - }] - }] - } - ); - expect(response.status).to.eql(200); - }); - describe("Verify the updated Business Partner", () => { - it("Verify the Address of Business Partner", async () => { - const response = await GET(`/odata/v4/api-business-partner/A_BusinessPartnerAddress?$filter=BusinessPartner eq '1004100'`); - expect(response.status).to.eql(200); - expect(response.data.value).to.exist; - expect(response.data.value[0]).to.contains({ - AddressID: "457", - }); - }); - - it("Verify the Email address of Business Partner", async () => { - const response = await GET(`/odata/v4/api-business-partner/A_AddressEmailAddress?$filter=AddressID eq '457'`); - expect(response.status).to.eql(200); - expect(response.data.value).to.exist; - expect(response.data.value[0]).to.contains({ - AddressID: "457", - Person: "johnson", - OrdinalNumber: "334", - EmailAddress: "sunny@test.com" - }); - }); - }); - }); - - it(`Should Close the Incident-${draftId}`, async ()=>{ - const {status} = await POST(`/odata/v4/processor/Incidents(ID=${draftId},IsActiveEntity=true)/ProcessorService.draftEdit`, - { - "PreserveChanges": true - }); - expect(status).to.equal(201); - }); - }); -}); + const { GET, POST, PATCH, expect, axios } = cds.test(__dirname + '/../xmpls/messaging','--with-mocks') + axios.defaults.auth = { username: "alice" } + + const bupa = '/odata/v4/api-business-partner' + const Incidents = '/odata/v4/processor/Incidents' + const edit = 'ProcessorService.draftEdit' + const activate = 'ProcessorService.draftActivate' + const active = 'IsActiveEntity=true' + const draft = 'IsActiveEntity=false' + let ID, id + + describe("GET should return 200", () => { + + it("Should return list of Business Partners", async () => { + const { status } = await GET `${bupa}/A_BusinessPartner` + expect(status).to.eql(200) + }) + + it("Should return list of Business Partners Address", async () => { + const { status } = await GET `${bupa}/A_BusinessPartnerAddress` + expect(status).to.eql(200) + }) + + it("Should return list of Business Partners Email Address", async () => { + const { status } = await GET `${bupa}/A_AddressEmailAddress` + expect(status).to.eql(200) + }) + + it("Should return list of Business Partners Address PhoneNumber", async () => { + const { status } = await GET `${bupa}/A_AddressPhoneNumber` + expect(status).to.eql(200) + }) + + }) + + + describe('Draft Choreography APIs', () => { + + it('Create an incident ', async () => { + let { status, data } = await POST(`${Incidents}`, { + title: 'Urgent attention required !', + status_code: 'N', + customer: { ID: '1004100' } + }) + expect(status).to.equal(201) + ID = `ID=${id=data.ID}` //> captures the newly created Incident's ID for subsequent use... + }) + + it('+ Activate the draft & check Urgency code as H using custom logic', async () => { + let { status, data } = await POST `${Incidents}(${ID},${draft})/${activate}` + expect(status).to.eql(201) + expect(data.urgency_code).to.eql('H') + }) + + it('+ Test the customer detail', async () => { + let { status, data } = await GET `${Incidents}?$filter=ID eq ${id}` + expect(status).to.eql(200) + expect(data.value).to.exist + expect(data.value[0]).to.contains({ + customer_ID: '1004100' + }) + }) + + describe("Create annd Update Business Partner", () => { + + it("Update Business Partner", async () => { + let { status } = await PATCH(`${bupa}/A_BusinessPartner('1004100')`, { + to_BusinessPartnerAddress: [{ + AddressID: "457", + to_EmailAddress: [{ + AddressID: "457", + Person: "johnson", + OrdinalNumber: "334", + EmailAddress: "sunny@test.com" + }] + }] + }) + expect(status).to.eql(200) + }) + + it("Verify the Address of Business Partner", async () => { + let { status, data } = await GET `${bupa}/A_BusinessPartnerAddress?$filter=BusinessPartner eq '1004100'` + expect(status).to.eql(200) + expect(data.value).to.exist + expect(data.value[0]).to.contains({ + AddressID: "457", + }) + }) + + it("Verify the Email address of Business Partner", async () => { + let { status, data } = await GET `${bupa}/A_AddressEmailAddress?$filter=AddressID eq '457'` + expect(status).to.eql(200) + expect(data.value).to.exist + expect(data.value[0]).to.contains({ + AddressID: "457", + Person: "johnson", + OrdinalNumber: "334", + EmailAddress: "sunny@test.com" + }) + }) + + }) + + it(`Should Close the Incident-${ID}`, async () => { + const { status } = await POST `${Incidents}(${ID},${active})/${edit}` + expect(status).to.equal(201) + }) + }) +}) diff --git a/test/remote-service.test.js b/test/remote-service.test.js index 21f5a23..9f63ae4 100644 --- a/test/remote-service.test.js +++ b/test/remote-service.test.js @@ -1,93 +1,87 @@ -const cds = require("@sap/cds"); +const cds = require("@sap/cds") describe("Integration Test for Remote Service", () => { - const { GET, POST, PATCH, expect, axios } = cds.test(__dirname + '/../xmpls/remote-service', '--with-mocks'); + const { GET, POST, PATCH , expect, axios} = cds.test(__dirname + '/../xmpls/remote-service', '--with-mocks') + axios.defaults.auth = { username: 'alice' } - axios.defaults.auth = { username: "alice" }; - let draftId,incidentId; - describe("Test the BusinessPartner GET Endpoints", () => { - - it("Should return list of Business Partners", async () => { - const response = await GET("/odata/v4/api-business-partner/A_BusinessPartner"); - expect(response.status).to.eql(200); - }); - - it("Should return list of Business Partners Address", async () => { - const response = await GET("/odata/v4/api-business-partner/A_BusinessPartnerAddress"); - expect(response.status).to.eql(200); - }); - it("Should return list of Business Partners Email Address", async () => { - const response = await GET("/odata/v4/api-business-partner/A_AddressEmailAddress"); - expect(response.status).to.eql(200); - }); - it("Should return list of Business Partners Address PhoneNumber", async () => { - const response = await GET("/odata/v4/api-business-partner/A_AddressPhoneNumber"); - expect(response.status).to.eql(200); - }); - }); + const bupa = '/odata/v4/api-business-partner' + const Incidents = '/odata/v4/processor/Incidents' + const edit = 'ProcessorService.draftEdit' + const activate = 'ProcessorService.draftActivate' + const active = 'IsActiveEntity=true' + const draft = 'IsActiveEntity=false' + let ID = null, id = null - describe('Draft Choreography APIs', () => { - it('Create an incident ', async () => { - const { status, statusText, data } = await POST(`/odata/v4/processor/Incidents`, { - title: 'Urgent attention required !', - status_code: 'N', - "customer": {ID:"1004100"} - }); - draftId = data.ID; - expect(status).to.equal(201); - expect(statusText).to.equal('Created'); - }); - it('+ Activate the draft & check Urgency code as H using custom logic', async () => { - const response = await POST( - `/odata/v4/processor/Incidents(ID=${draftId},IsActiveEntity=false)/ProcessorService.draftActivate` - ); - expect(response.status).to.eql(201); - expect(response.data.urgency_code).to.eql('H'); - }); - it('+ Test the customer detail', async () => { - const response = await GET(`/odata/v4/processor/Incidents?$filter=ID eq ${draftId}`); - //incidentId = ID; - expect(response.status).to.eql(200); - expect(response.data.value).to.exist; - expect(response.data.value[0]).to.contains({ - "customer_ID": "1004100" - }); - incidentId = response.data.ID; - }); - - describe("Create annd Update Business Partner", () => { - it("Creates a new Business Partner", async () => { - const payload = { - BusinessPartner: "17100015", - BusinessPartnerIsBlocked: true, - BusinessPartnerFullName: "John Doee", - }; - const response = await POST( - "/odata/v4/api-business-partner/A_BusinessPartner", - payload - ); - expect(response.status).to.eql(201); - }); - it("Update Business Partner", async () => { - const response = await PATCH( - `/odata/v4/api-business-partner/A_BusinessPartner('17100015')`, - {BusinessPartnerIsBlocked: false} - ); - expect(response.status).to.eql(200); - }); - }); - - it(`Should Close the Incident-${draftId}`, async ()=>{ - const {status} = await POST(`/odata/v4/processor/Incidents(ID=${draftId},IsActiveEntity=true)/ProcessorService.draftEdit`, - { - "PreserveChanges": true - }); - expect(status).to.equal(201); - }); - it(`Update Business Partner details of the Incident`, async ()=>{ - const {status } = await PATCH(`/odata/v4/processor/Incidents(ID=${draftId},IsActiveEntity=false)`,{customer_ID: '17100015'}); - expect(status).to.equal(200); - }); - }); -}); + describe("Test the BusinessPartner GET Endpoints", () => { + + it("Should return list of Business Partners", async () => { + const {status} = await GET `${bupa}/A_BusinessPartner` + expect(status).to.eql(200) + }) + + it("Should return list of Business Partners Address", async () => { + const {status} = await GET `${bupa}/A_BusinessPartnerAddress` + expect(status).to.eql(200) + }) + it("Should return list of Business Partners Email Address", async () => { + const {status} = await GET `${bupa}/A_AddressEmailAddress` + expect(status).to.eql(200) + }) + it("Should return list of Business Partners Address PhoneNumber", async () => { + const {status} = await GET `${bupa}/A_AddressPhoneNumber` + expect(status).to.eql(200) + }) + }) + + describe('Draft Choreography APIs', () => { + it('Create an incident ', async () => { + const { status, data } = await POST (`${Incidents}`, { + title: 'Urgent attention required !', + status_code: 'N', + "customer": { ID: "1004100" } + }) + expect(status).to.equal(201) + ID = `ID=${id=data.ID}` //> captures the newly created Incident's ID for subsequent use... + }) + it('+ Activate the draft & check Urgency code as H using custom logic', async () => { + const { status, data} = await POST `${Incidents}(${ID},${draft})/${activate}` + expect(status).to.eql(201) + expect(data.urgency_code).to.eql('H') + }) + it('+ Test the customer detail', async () => { + const { status, data } = await GET(`${Incidents}?$filter=ID eq ${id}`) + expect(status).to.eql(200) + expect(data.value).to.exist + expect(data.value[0]).to.contains({ + "customer_ID": "1004100" + }) + }) + + describe("Create and Update Business Partner", () => { + it("Creates a new Business Partner", async () => { + const {status} = await POST (`${bupa}/A_BusinessPartner`, { + BusinessPartner: "17100015", + BusinessPartnerIsBlocked: true, + BusinessPartnerFullName: "John Doee", + }) + expect(status).to.eql(201) + }) + it("Update Business Partner", async () => { + const {status} = await PATCH (`${bupa}/A_BusinessPartner('17100015')`, { + BusinessPartnerIsBlocked: false + }) + expect(status).to.eql(200) + }) + }) + + it(`Should Close the Incident-${id}`, async () => { + const {status} = await POST `${Incidents}(${ID},${active})/${edit}` + expect(status).to.equal(201) + }) + it(`Update Business Partner details of the Incident`, async () => { + const {status} = await PATCH(`${Incidents}(${ID},${draft})`, { customer_ID: '17100015' }) + expect(status).to.equal(200) + }) + }) +}) diff --git a/xmpls/messaging/srv/mashup.cds b/xmpls/messaging/srv/mashup.cds index 5cc44b0..4caf901 100644 --- a/xmpls/messaging/srv/mashup.cds +++ b/xmpls/messaging/srv/mashup.cds @@ -1,4 +1,31 @@ -using { ProcessorService } from '../../../srv/services'; -using from '../../../srv/services'; -using from '../../../app/services'; -annotate ProcessorService with @impl: '../xmpls/messaging/srv/services.js'; +// REVISIT: This file and all in ./external is copy from ../remote-service -> should be refactored + +using { ProcessorService } from '@capire/incidents/app/services'; +annotate ProcessorService with @impl: 'srv/services.js'; + +// REVISIT: This is not in line with our best practices. +using { API_BUSINESS_PARTNER as S4 } from './external/API_BUSINESS_PARTNER'; +service RemoteService { + entity BusinessPartner as projection on S4.A_BusinessPartner { + key BusinessPartner as ID, + FirstName as firstName, + LastName as lastName, + BusinessPartnerName as name, + to_BusinessPartnerAddress as addresses + } + entity BusinessPartnerAddress as projection on S4.A_BusinessPartnerAddress { + BusinessPartner as ID, + AddressID as addressId, + to_EmailAddress as email, + to_PhoneNumber as phoneNumber + } + entity EmailAddress as projection on S4.A_AddressEmailAddress { + key AddressID as addressId, + EmailAddress as email + } + + entity PhoneNumber as projection on S4.A_AddressPhoneNumber { + key AddressID as addressId, + PhoneNumber as phone + } +} diff --git a/xmpls/messaging/srv/remote.cds b/xmpls/messaging/srv/remote.cds deleted file mode 100644 index a03ea8e..0000000 --- a/xmpls/messaging/srv/remote.cds +++ /dev/null @@ -1,30 +0,0 @@ -/** -* Expose Remote Services with associations. Eventing/Messaging sample is an extension on top -* of Remote Service integration. This file is same as in Remote Service Sample -*/ -using { API_BUSINESS_PARTNER as S4 } from './external/API_BUSINESS_PARTNER'; - -service RemoteService { - entity BusinessPartner as projection on S4.A_BusinessPartner { - key BusinessPartner as ID, - FirstName as firstName, - LastName as lastName, - BusinessPartnerName as name, - to_BusinessPartnerAddress as addresses - } - entity BusinessPartnerAddress as projection on S4.A_BusinessPartnerAddress { - BusinessPartner as ID, - AddressID as addressId, - to_EmailAddress as email, - to_PhoneNumber as phoneNumber - } - entity EmailAddress as projection on S4.A_AddressEmailAddress { - key AddressID as addressId, - EmailAddress as email - } - - entity PhoneNumber as projection on S4.A_AddressPhoneNumber { - key AddressID as addressId, - PhoneNumber as phone - } -} \ No newline at end of file diff --git a/xmpls/messaging/srv/services.js b/xmpls/messaging/srv/services.js index e170a96..f5f7189 100644 --- a/xmpls/messaging/srv/services.js +++ b/xmpls/messaging/srv/services.js @@ -1,6 +1,6 @@ -/** -* Same as Remote Service Sample. Added additional Handlers for recieving and -* handling events/messages +/** +* Same as Remote Service Sample. Added additional Handlers for recieving and +* handling events/messages */ const cds = require('@sap/cds') @@ -12,7 +12,7 @@ class ProcessorService extends cds.ApplicationService { this.on('READ', 'Customers', (req) => this.onCustomerRead(req)); this.on(['CREATE','UPDATE'], 'Incidents', (req, next) => this.onCustomerCache(req, next)); this.S4bupa = await cds.connect.to('API_BUSINESS_PARTNER'); - this.remoteService = await cds.connect.to("RemoteService"); + this.remoteService = await cds.connect.to("RemoteService"); // REVISIT: What is this for? // Added Handlers for Eventing on top of remote service sample this.messaging = await cds.connect.to('messaging'); @@ -58,7 +58,7 @@ class ProcessorService extends cds.ApplicationService { }) }) }).where({ ID: newCustomerId })); - + if(customer) { customer.email = customer.addresses[0]?.email[0]?.email; customer.phone = customer.addresses[0]?.phoneNumber[0]?.phone; @@ -75,7 +75,7 @@ class ProcessorService extends cds.ApplicationService { console.log('>> delegating to S4 service...', req.query); const top = parseInt(req._queryOptions?.$top) || 100; const skip = parseInt(req._queryOptions?.$skip) || 0; - + const { BusinessPartner } = this.remoteService.entities; // Expands are required as the runtime does not support path expressions for remote services @@ -88,7 +88,7 @@ class ProcessorService extends cds.ApplicationService { }); }) }).limit(top, skip)); - + result = result.map((bp) => ({ ID: bp.ID, name: bp.name, @@ -100,7 +100,7 @@ class ProcessorService extends cds.ApplicationService { console.log("after result", result); return result; } - + changeUrgencyDueToSubject(data) { if (data) { diff --git a/xmpls/remote-service/srv/mashup.cds b/xmpls/remote-service/srv/mashup.cds index e2199cd..7ba99fc 100644 --- a/xmpls/remote-service/srv/mashup.cds +++ b/xmpls/remote-service/srv/mashup.cds @@ -1,4 +1,29 @@ -using { ProcessorService } from '../../../srv/services'; -using from '../../../srv/services'; -using from '../../../app/services'; -annotate ProcessorService with @impl: '../xmpls/remote-service/srv/services.js'; +using { ProcessorService } from '@capire/incidents/app/services'; +annotate ProcessorService with @impl: 'srv/services.js'; + +// REVISIT: This is not in line with our best practices. +using { API_BUSINESS_PARTNER as S4 } from './external/API_BUSINESS_PARTNER'; +service RemoteService { + entity BusinessPartner as projection on S4.A_BusinessPartner { + key BusinessPartner as ID, + FirstName as firstName, + LastName as lastName, + BusinessPartnerName as name, + to_BusinessPartnerAddress as addresses + } + entity BusinessPartnerAddress as projection on S4.A_BusinessPartnerAddress { + BusinessPartner as ID, + AddressID as addressId, + to_EmailAddress as email, + to_PhoneNumber as phoneNumber + } + entity EmailAddress as projection on S4.A_AddressEmailAddress { + key AddressID as addressId, + EmailAddress as email + } + + entity PhoneNumber as projection on S4.A_AddressPhoneNumber { + key AddressID as addressId, + PhoneNumber as phone + } +} diff --git a/xmpls/remote-service/srv/remote.cds b/xmpls/remote-service/srv/remote.cds deleted file mode 100644 index 2d85da7..0000000 --- a/xmpls/remote-service/srv/remote.cds +++ /dev/null @@ -1,26 +0,0 @@ -using { API_BUSINESS_PARTNER as S4 } from './external/API_BUSINESS_PARTNER'; - -service RemoteService { - entity BusinessPartner as projection on S4.A_BusinessPartner { - key BusinessPartner as ID, - FirstName as firstName, - LastName as lastName, - BusinessPartnerName as name, - to_BusinessPartnerAddress as addresses - } - entity BusinessPartnerAddress as projection on S4.A_BusinessPartnerAddress { - BusinessPartner as ID, - AddressID as addressId, - to_EmailAddress as email, - to_PhoneNumber as phoneNumber - } - entity EmailAddress as projection on S4.A_AddressEmailAddress { - key AddressID as addressId, - EmailAddress as email - } - - entity PhoneNumber as projection on S4.A_AddressPhoneNumber { - key AddressID as addressId, - PhoneNumber as phone - } -} \ No newline at end of file diff --git a/xmpls/remote-service/srv/services.js b/xmpls/remote-service/srv/services.js index bddb5d4..afdb70b 100644 --- a/xmpls/remote-service/srv/services.js +++ b/xmpls/remote-service/srv/services.js @@ -8,7 +8,7 @@ class ProcessorService extends cds.ApplicationService { this.on('READ', 'Customers', (req) => this.onCustomerRead(req)); this.on(['CREATE','UPDATE'], 'Incidents', (req, next) => this.onCustomerCache(req, next)); this.S4bupa = await cds.connect.to('API_BUSINESS_PARTNER'); - this.remoteService = await cds.connect.to('RemoteService'); + this.remoteService = await cds.connect.to('RemoteService'); // REVISIT: What is this for? return super.init(); } @@ -33,7 +33,7 @@ class ProcessorService extends cds.ApplicationService { }) }) }).where({ ID: newCustomerId })); - + if(customer) { customer.email = customer.addresses[0]?.email[0]?.email; customer.phone = customer.addresses[0]?.phoneNumber[0]?.phone; @@ -50,7 +50,7 @@ class ProcessorService extends cds.ApplicationService { console.log('>> delegating to S4 service...', req.query); const top = parseInt(req._queryOptions?.$top) || 100; const skip = parseInt(req._queryOptions?.$skip) || 0; - + const { BusinessPartner } = this.remoteService.entities; // Expands are required as the runtime does not support path expressions for remote services @@ -63,7 +63,7 @@ class ProcessorService extends cds.ApplicationService { }); }) }).limit(top, skip)); - + result = result.map((bp) => ({ ID: bp.ID, name: bp.name, @@ -75,7 +75,7 @@ class ProcessorService extends cds.ApplicationService { console.log("after result", result); return result; } - + changeUrgencyDueToSubject(data) { if (data) { From 14bd9240c80574659c61bf43ad695e4b648826ca Mon Sep 17 00:00:00 2001 From: Daniel Hutzel Date: Thu, 7 Nov 2024 10:24:59 +0100 Subject: [PATCH 07/20] jest --colors --- .github/workflows/create-test-branch.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/create-test-branch.yml b/.github/workflows/create-test-branch.yml index fce146a..492833c 100644 --- a/.github/workflows/create-test-branch.yml +++ b/.github/workflows/create-test-branch.yml @@ -17,12 +17,12 @@ jobs: run: | npm run add-all-xmpls rm -rf xmpls - + - name: Test run: | npm i - npm test - + npm test -- --colors + - name: Extract last commit author email and name id: extract_commit_info run: | From 07fb461e1b033f64219b70f6b1670730cdae2495 Mon Sep 17 00:00:00 2001 From: Daniel Hutzel Date: Thu, 7 Nov 2024 10:27:25 +0100 Subject: [PATCH 08/20] jest --colors --- .github/workflows/node.js.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 3393473..f84b4da 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -26,7 +26,7 @@ jobs: with: node-version: ${{ matrix.node-version }} - run: npm i - - run: npm test + - run: npm test -- --colors push: name: Push to CDS Test branch From eac67a19248a2be7edb7430f23f3b3e21bacf4a3 Mon Sep 17 00:00:00 2001 From: Daniel Hutzel Date: Thu, 7 Nov 2024 10:32:14 +0100 Subject: [PATCH 09/20] @capire/incidents --- xmpls/messaging/srv/mashup.cds | 2 +- xmpls/remote-service/srv/mashup.cds | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/xmpls/messaging/srv/mashup.cds b/xmpls/messaging/srv/mashup.cds index 4caf901..df3fa5f 100644 --- a/xmpls/messaging/srv/mashup.cds +++ b/xmpls/messaging/srv/mashup.cds @@ -1,6 +1,6 @@ // REVISIT: This file and all in ./external is copy from ../remote-service -> should be refactored -using { ProcessorService } from '@capire/incidents/app/services'; +using { ProcessorService } from '../../../app/services'; annotate ProcessorService with @impl: 'srv/services.js'; // REVISIT: This is not in line with our best practices. diff --git a/xmpls/remote-service/srv/mashup.cds b/xmpls/remote-service/srv/mashup.cds index 7ba99fc..46212a5 100644 --- a/xmpls/remote-service/srv/mashup.cds +++ b/xmpls/remote-service/srv/mashup.cds @@ -1,4 +1,4 @@ -using { ProcessorService } from '@capire/incidents/app/services'; +using { ProcessorService } from '../../../app/services'; annotate ProcessorService with @impl: 'srv/services.js'; // REVISIT: This is not in line with our best practices. From 78df2d2eea636c46a084c5a9c0c6cec30ca0cded Mon Sep 17 00:00:00 2001 From: Daniel Hutzel Date: Thu, 7 Nov 2024 10:54:06 +0100 Subject: [PATCH 10/20] prepate for using cds.utils.append() --- .github/workflows/checkout | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/checkout b/.github/workflows/checkout index ce42672..14ce5ff 100755 --- a/.github/workflows/checkout +++ b/.github/workflows/checkout @@ -2,8 +2,7 @@ /* eslint-disable no-console */ const cds = require("@sap/cds") -const { read, write, path } = cds.utils -const { promises:fs } = require("fs") +const { read, write, append=_append, fs, path } = cds.utils const _stringified = o => JSON.stringify(o,null,2) const checkout = { @@ -13,7 +12,7 @@ const checkout = { const base = await read ('package.json') for (let each of ['API_BUSINESS_PARTNER']) base.cds.requires[each] = xmpls.cds.requires[each] - await write (_stringified(base)).to('package.json') + await write (_stringified(base)) .to ('package.json') }, async messaging () { @@ -21,12 +20,14 @@ const checkout = { const base = await read ('package.json') for (let each of ['API_BUSINESS_PARTNER','messaging']) base.cds.requires[each] = xmpls.cds.requires[each] - await write (_stringified(base)).to('package.json') - await fs.appendFile (path.join(cds.root,'srv','services.cds'), ` - using from './incidents/field'; // Add UI fields for email in annotation - `) + await write (_stringified(base)) .to ('package.json') + await append ('\n'+`using from './incidents/field'; //> adds email fields to UI`+'\n') .to ('app/services.cds') } } +function _append(str) { + return { to: file => fs.promises.appendFile(path.join(cds.root,file), str) } +} + const [,,$1] = process.argv checkout[$1]?.() || console.log('Usage: ./checkout remote-service | messaging') From d5d3c41acee36a24e46061e05d75b4624a87608a Mon Sep 17 00:00:00 2001 From: Daniel Hutzel Date: Thu, 7 Nov 2024 10:57:17 +0100 Subject: [PATCH 11/20] .. --- .github/workflows/checkout | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/checkout b/.github/workflows/checkout index 14ce5ff..674ac50 100755 --- a/.github/workflows/checkout +++ b/.github/workflows/checkout @@ -1,10 +1,12 @@ #!/usr/bin/env node -/* eslint-disable no-console */ -const cds = require("@sap/cds") -const { read, write, append=_append, fs, path } = cds.utils +// helpers +const _append = str => ({ to: file => cds.utils.fs.promises.appendFile(cds.utils.path.join(cds.root,file), str) }) const _stringified = o => JSON.stringify(o,null,2) +const cds = require("@sap/cds") +const { read, write, append=_append } = cds.utils + const checkout = { async 'remote-service' () { @@ -25,9 +27,5 @@ const checkout = { } } -function _append(str) { - return { to: file => fs.promises.appendFile(path.join(cds.root,file), str) } -} - const [,,$1] = process.argv checkout[$1]?.() || console.log('Usage: ./checkout remote-service | messaging') From f5822590191fc8bf20742594becb5c04c0d130dc Mon Sep 17 00:00:00 2001 From: Daniel Hutzel Date: Thu, 7 Nov 2024 11:17:07 +0100 Subject: [PATCH 12/20] more cosmetics --- .github/workflows/checkout | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/.github/workflows/checkout b/.github/workflows/checkout index 674ac50..41f4630 100755 --- a/.github/workflows/checkout +++ b/.github/workflows/checkout @@ -1,31 +1,34 @@ #!/usr/bin/env node -// helpers -const _append = str => ({ to: file => cds.utils.fs.promises.appendFile(cds.utils.path.join(cds.root,file), str) }) -const _stringified = o => JSON.stringify(o,null,2) - const cds = require("@sap/cds") const { read, write, append=_append } = cds.utils const checkout = { async 'remote-service' () { - const xmpls = await read ('xmpls/remote-service/package.json') - const base = await read ('package.json') + let xmpls = await read ('xmpls/remote-service/package.json') + let base = await read ('package.json') for (let each of ['API_BUSINESS_PARTNER']) base.cds.requires[each] = xmpls.cds.requires[each] - await write (_stringified(base)) .to ('package.json') + if (append === _append) base = _formatted(base) //> for older cds versions only + await write (base) .to ('package.json') }, async messaging () { - const xmpls = await read ('xmpls/messaging/package.json') - const base = await read ('package.json') + await append ('\n'+`using from './incidents/field'; //> adds email fields to UI`+'\n') .to ('app/services.cds') + let xmpls = await read ('xmpls/messaging/package.json') + let base = await read ('package.json') for (let each of ['API_BUSINESS_PARTNER','messaging']) base.cds.requires[each] = xmpls.cds.requires[each] - await write (_stringified(base)) .to ('package.json') - await append ('\n'+`using from './incidents/field'; //> adds email fields to UI`+'\n') .to ('app/services.cds') + if (append === _append) base = _formatted(base) //> for older cds versions only + await write (base) .to ('package.json') } } const [,,$1] = process.argv checkout[$1]?.() || console.log('Usage: ./checkout remote-service | messaging') + +// ------------------------------------------------------------------------ +// fixes for missing features in older cds versions +function _append (str) { return { to: file => cds.utils.fs.promises.appendFile(cds.utils.path.join(cds.root,file), str) }} +function _formatted (json) { return JSON.stringify(json,null,2) } From 0639ab9f450639d07f2184aacf9da3932c8df800 Mon Sep 17 00:00:00 2001 From: Daniel Hutzel Date: Thu, 7 Nov 2024 12:56:14 +0100 Subject: [PATCH 13/20] improved checkout technique --- .github/workflows/checkout | 10 ++++++++-- xmpls/messaging/package.json | 6 +++--- xmpls/messaging/services.cds | 3 +++ xmpls/messaging/srv/mashup.cds | 4 ---- xmpls/messaging/{ => test}/req.http | 0 xmpls/remote-service/services.cds | 3 +++ xmpls/remote-service/srv/mashup.cds | 3 --- 7 files changed, 17 insertions(+), 12 deletions(-) create mode 100644 xmpls/messaging/services.cds rename xmpls/messaging/{ => test}/req.http (100%) create mode 100644 xmpls/remote-service/services.cds diff --git a/.github/workflows/checkout b/.github/workflows/checkout index 41f4630..d6aa3b2 100755 --- a/.github/workflows/checkout +++ b/.github/workflows/checkout @@ -1,7 +1,7 @@ #!/usr/bin/env node const cds = require("@sap/cds") -const { read, write, append=_append } = cds.utils +const { copy, read, write, append=_append } = cds.utils const checkout = { @@ -15,7 +15,13 @@ const checkout = { }, async messaging () { - await append ('\n'+`using from './incidents/field'; //> adds email fields to UI`+'\n') .to ('app/services.cds') + // copy content from xmpls/messaging to incidents... + for (let each of ['app','srv']) + copy('xmpls/messaging/'+each).to(each) + // add email fields to UI + await append ('\n'+`using from './incidents/field';`+'\n') + .to ('app/services.cds') + // enhance package.json let xmpls = await read ('xmpls/messaging/package.json') let base = await read ('package.json') for (let each of ['API_BUSINESS_PARTNER','messaging']) diff --git a/xmpls/messaging/package.json b/xmpls/messaging/package.json index 7759e67..1cad7f2 100644 --- a/xmpls/messaging/package.json +++ b/xmpls/messaging/package.json @@ -98,10 +98,10 @@ "messaging": { "kind": "local-messaging", "[production]": { - "kind": "enterprise-messaging-shared", - "format": "cloudevents" + "kind": "enterprise-messaging-shared", + "format": "cloudevents" } - } + } } } } \ No newline at end of file diff --git a/xmpls/messaging/services.cds b/xmpls/messaging/services.cds new file mode 100644 index 0000000..ebe3849 --- /dev/null +++ b/xmpls/messaging/services.cds @@ -0,0 +1,3 @@ +// Using local service implementation +using { ProcessorService } from '../../app/services'; +annotate ProcessorService with @impl: 'srv/services.js'; diff --git a/xmpls/messaging/srv/mashup.cds b/xmpls/messaging/srv/mashup.cds index df3fa5f..704189d 100644 --- a/xmpls/messaging/srv/mashup.cds +++ b/xmpls/messaging/srv/mashup.cds @@ -1,8 +1,4 @@ // REVISIT: This file and all in ./external is copy from ../remote-service -> should be refactored - -using { ProcessorService } from '../../../app/services'; -annotate ProcessorService with @impl: 'srv/services.js'; - // REVISIT: This is not in line with our best practices. using { API_BUSINESS_PARTNER as S4 } from './external/API_BUSINESS_PARTNER'; service RemoteService { diff --git a/xmpls/messaging/req.http b/xmpls/messaging/test/req.http similarity index 100% rename from xmpls/messaging/req.http rename to xmpls/messaging/test/req.http diff --git a/xmpls/remote-service/services.cds b/xmpls/remote-service/services.cds new file mode 100644 index 0000000..ebe3849 --- /dev/null +++ b/xmpls/remote-service/services.cds @@ -0,0 +1,3 @@ +// Using local service implementation +using { ProcessorService } from '../../app/services'; +annotate ProcessorService with @impl: 'srv/services.js'; diff --git a/xmpls/remote-service/srv/mashup.cds b/xmpls/remote-service/srv/mashup.cds index 46212a5..a8fd8f6 100644 --- a/xmpls/remote-service/srv/mashup.cds +++ b/xmpls/remote-service/srv/mashup.cds @@ -1,6 +1,3 @@ -using { ProcessorService } from '../../../app/services'; -annotate ProcessorService with @impl: 'srv/services.js'; - // REVISIT: This is not in line with our best practices. using { API_BUSINESS_PARTNER as S4 } from './external/API_BUSINESS_PARTNER'; service RemoteService { From 93a82c15bf8c28ae3be12abf0e120acb29971c2c Mon Sep 17 00:00:00 2001 From: Daniel Hutzel Date: Thu, 7 Nov 2024 15:34:46 +0100 Subject: [PATCH 14/20] . --- .github/workflows/checkout | 54 ++++++++++++++++---------------------- package.json | 4 +-- 2 files changed, 25 insertions(+), 33 deletions(-) diff --git a/.github/workflows/checkout b/.github/workflows/checkout index d6aa3b2..f827237 100755 --- a/.github/workflows/checkout +++ b/.github/workflows/checkout @@ -1,40 +1,32 @@ #!/usr/bin/env node +const { fs, path, exists, copy, read, write, append=_append } = require("@sap/cds").utils -const cds = require("@sap/cds") -const { copy, read, write, append=_append } = cds.utils - -const checkout = { - - async 'remote-service' () { - let xmpls = await read ('xmpls/remote-service/package.json') - let base = await read ('package.json') - for (let each of ['API_BUSINESS_PARTNER']) - base.cds.requires[each] = xmpls.cds.requires[each] - if (append === _append) base = _formatted(base) //> for older cds versions only - await write (base) .to ('package.json') - }, - - async messaging () { - // copy content from xmpls/messaging to incidents... - for (let each of ['app','srv']) - copy('xmpls/messaging/'+each).to(each) - // add email fields to UI - await append ('\n'+`using from './incidents/field';`+'\n') - .to ('app/services.cds') - // enhance package.json - let xmpls = await read ('xmpls/messaging/package.json') - let base = await read ('package.json') - for (let each of ['API_BUSINESS_PARTNER','messaging']) - base.cds.requires[each] = xmpls.cds.requires[each] - if (append === _append) base = _formatted(base) //> for older cds versions only - await write (base) .to ('package.json') - } +async function checkout (xmpl, ...requires) { + // copy content from xmpl to incidents... + await Promise.all (['app','srv','db','test'] .map (async each => { + let src = `xmpls/${xmpl}/${each}` + if (exists(src)) return await copy(src).to(each) + })) + // enhance package.json + let xmpls = await read (`xmpls/${xmpl}/package.json`) + let base = await read ('package.json') + for (let each of requires) base.cds.requires[each] = xmpls.cds.requires[each] + if (append === _append) base = _formatted(base) //> for older cds versions only + await write (base) .to ('package.json') } +checkout['remote-service'] = ()=> checkout ('remote-service', 'API_BUSINESS_PARTNER') +checkout['messaging'] = ()=> Promise.all([ + checkout ('messaging', 'messaging', 'API_BUSINESS_PARTNER'), + append ('\n'+`using from './incidents/field';`+'\n') .to ('app/services.cds') // add email fields to UI +]) + +// actually run the checkout... const [,,$1] = process.argv -checkout[$1]?.() || console.log('Usage: ./checkout remote-service | messaging') +checkout[$1]?.().catch(console.error) +|| console.log('Usage: ./checkout remote-service | messaging') // ------------------------------------------------------------------------ // fixes for missing features in older cds versions -function _append (str) { return { to: file => cds.utils.fs.promises.appendFile(cds.utils.path.join(cds.root,file), str) }} +function _append (str) { return { to: file => fs.promises.appendFile(path.join(cds.root,file), str) }} function _formatted (json) { return JSON.stringify(json,null,2) } diff --git a/package.json b/package.json index 80ea7b3..b28ff31 100644 --- a/package.json +++ b/package.json @@ -35,8 +35,8 @@ "add-attachments": "npm add @cap-js/attachments && cp -r xmpls/attachments.cds ./srv", "add-notifications": "npm add @cap-js/notifications && cp xmpls/alert-notifications.js ./srv && cp xmpls/notification-types.json ./srv", "add-audit-log": "npm add @cap-js/audit-logging && cp xmpls/data-privacy.cds ./srv", - "add-remote-service": "./.github/workflows/checkout remote-service", - "add-messaging": "./.github/workflows/checkout messaging", + "add-remote-service": ".github/workflows/checkout remote-service", + "add-messaging": ".github/workflows/checkout messaging", "add-all-xmpls": "npm run add-remote-service && npm run add-messaging && npm run add-change-tracking && npm run add-audit-log", "reset": "read -p 'This will irreversibly reset your working directory including ALL files in this git repo. Continue?' -n 1 -r && echo && if [[ $REPLY =~ ^[Yy]$ ]]; then git clean -fd && git reset --hard && npm i; fi" }, From b2f67f44a44a9d27077766d2cf5f7162b6fbb8a1 Mon Sep 17 00:00:00 2001 From: Daniel Hutzel Date: Thu, 7 Nov 2024 15:38:33 +0100 Subject: [PATCH 15/20] ... --- .github/workflows/checkout | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/checkout b/.github/workflows/checkout index f827237..7fc8c3d 100755 --- a/.github/workflows/checkout +++ b/.github/workflows/checkout @@ -15,7 +15,9 @@ async function checkout (xmpl, ...requires) { await write (base) .to ('package.json') } -checkout['remote-service'] = ()=> checkout ('remote-service', 'API_BUSINESS_PARTNER') +checkout['remote-service'] = ()=> + checkout ('remote-service', 'API_BUSINESS_PARTNER') + checkout['messaging'] = ()=> Promise.all([ checkout ('messaging', 'messaging', 'API_BUSINESS_PARTNER'), append ('\n'+`using from './incidents/field';`+'\n') .to ('app/services.cds') // add email fields to UI @@ -23,8 +25,8 @@ checkout['messaging'] = ()=> Promise.all([ // actually run the checkout... const [,,$1] = process.argv -checkout[$1]?.().catch(console.error) -|| console.log('Usage: ./checkout remote-service | messaging') +if ($1 in checkout) checkout[$1]().catch(console.error) +else console.log('Usage: ./checkout remote-service | messaging') // ------------------------------------------------------------------------ // fixes for missing features in older cds versions From 59a809c902bd4e07e4868c9a0eb460a674a6700f Mon Sep 17 00:00:00 2001 From: Daniel Hutzel Date: Thu, 7 Nov 2024 15:40:40 +0100 Subject: [PATCH 16/20] .... --- .github/workflows/checkout | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/checkout b/.github/workflows/checkout index 7fc8c3d..49bb3df 100755 --- a/.github/workflows/checkout +++ b/.github/workflows/checkout @@ -24,9 +24,8 @@ checkout['messaging'] = ()=> Promise.all([ ]) // actually run the checkout... -const [,,$1] = process.argv -if ($1 in checkout) checkout[$1]().catch(console.error) -else console.log('Usage: ./checkout remote-service | messaging') +const cmd = checkout[process.argv[2]] +cmd?.().catch(console.error) || console.log('Usage: ./checkout remote-service | messaging') // ------------------------------------------------------------------------ // fixes for missing features in older cds versions From bf0bfc77ca8fdb73876e4bc8b767c85f6d31d942 Mon Sep 17 00:00:00 2001 From: Daniel Hutzel Date: Thu, 7 Nov 2024 15:44:52 +0100 Subject: [PATCH 17/20] ..... --- .github/workflows/checkout | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/checkout b/.github/workflows/checkout index 49bb3df..9a76adc 100755 --- a/.github/workflows/checkout +++ b/.github/workflows/checkout @@ -25,7 +25,9 @@ checkout['messaging'] = ()=> Promise.all([ // actually run the checkout... const cmd = checkout[process.argv[2]] -cmd?.().catch(console.error) || console.log('Usage: ./checkout remote-service | messaging') +cmd?.().catch(console.error) || console.error ( + `Usage: ${path.relative(process.cwd(),__filename)} ${Object.keys(checkout).join('|')}` +) // ------------------------------------------------------------------------ // fixes for missing features in older cds versions From 5b8d8ddad9c57f2e287155afc40a3f5689475245 Mon Sep 17 00:00:00 2001 From: Daniel Hutzel Date: Thu, 7 Nov 2024 15:45:50 +0100 Subject: [PATCH 18/20] ...... --- .github/workflows/checkout | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/checkout b/.github/workflows/checkout index 9a76adc..d05905f 100755 --- a/.github/workflows/checkout +++ b/.github/workflows/checkout @@ -24,8 +24,7 @@ checkout['messaging'] = ()=> Promise.all([ ]) // actually run the checkout... -const cmd = checkout[process.argv[2]] -cmd?.().catch(console.error) || console.error ( +checkout[process.argv[2]]?.().catch(console.error) || console.error ( `Usage: ${path.relative(process.cwd(),__filename)} ${Object.keys(checkout).join('|')}` ) From 9705ab13b493d00554410dbbb7f8a1f11cd53557 Mon Sep 17 00:00:00 2001 From: Daniel Hutzel Date: Thu, 7 Nov 2024 15:51:35 +0100 Subject: [PATCH 19/20] ....... --- .github/workflows/checkout | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/checkout b/.github/workflows/checkout index d05905f..a200387 100755 --- a/.github/workflows/checkout +++ b/.github/workflows/checkout @@ -15,17 +15,16 @@ async function checkout (xmpl, ...requires) { await write (base) .to ('package.json') } -checkout['remote-service'] = ()=> +exports['remote-service'] = ()=> checkout ('remote-service', 'API_BUSINESS_PARTNER') -checkout['messaging'] = ()=> Promise.all([ +exports['messaging'] = ()=> Promise.all([ checkout ('messaging', 'messaging', 'API_BUSINESS_PARTNER'), append ('\n'+`using from './incidents/field';`+'\n') .to ('app/services.cds') // add email fields to UI ]) -// actually run the checkout... -checkout[process.argv[2]]?.().catch(console.error) || console.error ( - `Usage: ${path.relative(process.cwd(),__filename)} ${Object.keys(checkout).join('|')}` +if (!module.parent) exports[process.argv[2]]?.().catch(console.error) || console.log ( + `Usage: ${path.relative(process.cwd(),__filename)} ${Object.keys(exports).join('|')}` ) // ------------------------------------------------------------------------ From 5ce58eaec123de0b0baefa59fd7c6052ac425dd4 Mon Sep 17 00:00:00 2001 From: Daniel Hutzel Date: Thu, 7 Nov 2024 15:54:42 +0100 Subject: [PATCH 20/20] . --- cds-plugin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cds-plugin.js b/cds-plugin.js index 4f6582f..f964a1e 100644 --- a/cds-plugin.js +++ b/cds-plugin.js @@ -1,4 +1,4 @@ -const cds = require("@sap/cds"); +const cds = require("@sap/cds") cds.once('bootstrap', (app) => { app.serve('/incidents/app').from(__dirname,'/app/incidents/webapp') })