From af9e0545b9f6dbd1377faf46d4142a51db28ee97 Mon Sep 17 00:00:00 2001 From: Albin Ramovic <68844975+aramovic79@users.noreply.github.com> Date: Fri, 20 Sep 2024 09:10:27 +0200 Subject: [PATCH] fix: Use appName as package name in the apiResources.partOfPackage (#59) * global.namespace => global.appName changes * add tests for the partOfPackage property * Update __tests__/ord.test.js Thanks Tai! Co-authored-by: Duc Tai Ly <124802873+ductaily@users.noreply.github.com> * mock the cds.root property * minor change - change name in the bookshop.package.json * fix linter error * suppress no-useless-escape linter error --------- Co-authored-by: Duc Tai Ly <124802873+ductaily@users.noreply.github.com> --- __tests__/__snapshots__/ord.test.js.snap | 48 +++++----- __tests__/bookshop/package.json | 2 +- __tests__/ord.test.js | 111 +++++++++++++++-------- lib/ord.js | 12 +-- 4 files changed, 105 insertions(+), 68 deletions(-) diff --git a/__tests__/__snapshots__/ord.test.js.snap b/__tests__/__snapshots__/ord.test.js.snap index 257d704..a7443ce 100644 --- a/__tests__/__snapshots__/ord.test.js.snap +++ b/__tests__/__snapshots__/ord.test.js.snap @@ -18,11 +18,11 @@ exports[`Tests for default ORD document Successfully create ORD Documents with d "extensible": { "supported": "no", }, - "ordId": "capjs.ord:apiResource:undefined.AdminService:v1", + "ordId": "capire.bookshopordsample:apiResource:undefined.AdminService:v1", "partOfGroups": [ - "sap.cds:service:capjs.ord:undefined.AdminService", + "sap.cds:service:capire.bookshopordsample:undefined.AdminService", ], - "partOfPackage": "capjsord:package:undefined:v1", + "partOfPackage": "capirebookshopordsample:package:undefined:v1", "releaseStatus": "active", "resourceDefinitions": [ { @@ -65,11 +65,11 @@ exports[`Tests for default ORD document Successfully create ORD Documents with d "extensible": { "supported": "no", }, - "ordId": "capjs.ord:apiResource:undefined.CatalogService:v1", + "ordId": "capire.bookshopordsample:apiResource:undefined.CatalogService:v1", "partOfGroups": [ - "sap.cds:service:capjs.ord:undefined.CatalogService", + "sap.cds:service:capire.bookshopordsample:undefined.CatalogService", ], - "partOfPackage": "capjsord:package:undefined:v1", + "partOfPackage": "capirebookshopordsample:package:undefined:v1", "releaseStatus": "active", "resourceDefinitions": [ { @@ -106,11 +106,11 @@ exports[`Tests for default ORD document Successfully create ORD Documents with d "extensible": { "supported": "no", }, - "ordId": "capjs.ord:eventResource:undefined.AdminService:v1", + "ordId": "capire.bookshopordsample:eventResource:undefined.AdminService:v1", "partOfGroups": [ - "sap.cds:service:capjs.ord:undefined.AdminService", + "sap.cds:service:capire.bookshopordsample:undefined.AdminService", ], - "partOfPackage": "capjsord:package:undefined:v1", + "partOfPackage": "capirebookshopordsample:package:undefined:v1", "releaseStatus": "beta", "resourceDefinitions": [ { @@ -125,7 +125,7 @@ exports[`Tests for default ORD document Successfully create ORD Documents with d }, ], "shortDescription": "Example ODM Event", - "title": "ODM capjsord Events", + "title": "ODM capirebookshopordsample Events", "version": "1.0.0", "visibility": "public", }, @@ -134,11 +134,11 @@ exports[`Tests for default ORD document Successfully create ORD Documents with d "extensible": { "supported": "no", }, - "ordId": "capjs.ord:eventResource:undefined.CatalogService:v1", + "ordId": "capire.bookshopordsample:eventResource:undefined.CatalogService:v1", "partOfGroups": [ - "sap.cds:service:capjs.ord:undefined.CatalogService", + "sap.cds:service:capire.bookshopordsample:undefined.CatalogService", ], - "partOfPackage": "capjsord:package:undefined:v1", + "partOfPackage": "capirebookshopordsample:package:undefined:v1", "releaseStatus": "beta", "resourceDefinitions": [ { @@ -153,19 +153,19 @@ exports[`Tests for default ORD document Successfully create ORD Documents with d }, ], "shortDescription": "Example ODM Event", - "title": "ODM capjsord Events", + "title": "ODM capirebookshopordsample Events", "version": "1.0.0", "visibility": "public", }, ], "groups": [ { - "groupId": "sap.cds:service:capjs.ord:undefined.AdminService", + "groupId": "sap.cds:service:capire.bookshopordsample:undefined.AdminService", "groupTypeId": "sap.cds:service", "title": "Admin Service", }, { - "groupId": "sap.cds:service:capjs.ord:undefined.CatalogService", + "groupId": "sap.cds:service:capire.bookshopordsample:undefined.CatalogService", "groupTypeId": "sap.cds:service", "title": "Catalog Service", }, @@ -173,13 +173,13 @@ exports[`Tests for default ORD document Successfully create ORD Documents with d "openResourceDiscovery": "1.9", "packages": [ { - "description": "Description for capjs ord", - "ordId": "capjsord:package:undefined:v1", + "description": "Description for capire bookshop ord sample", + "ordId": "capirebookshopordsample:package:undefined:v1", "partOfProducts": [ - "customer:product:capjs.ord:", + "customer:product:capire.bookshop.ord.sample:", ], - "shortDescription": "Short description for capjs ord", - "title": "capjs ord", + "shortDescription": "Short description for capire bookshop ord sample", + "title": "capire bookshop ord sample", "vendor": "customer:vendor:Customer:", "version": "1.0.0", }, @@ -187,9 +187,9 @@ exports[`Tests for default ORD document Successfully create ORD Documents with d "policyLevel": "none", "products": [ { - "ordId": "customer:product:cap.js.ord:", - "shortDescription": "Description for cap js ord", - "title": "cap js ord", + "ordId": "customer:product:capire.bookshop.ord.sample:", + "shortDescription": "Description for capire bookshop ord sample", + "title": "capire bookshop ord sample", "vendor": "customer:vendor:customer:", }, ], diff --git a/__tests__/bookshop/package.json b/__tests__/bookshop/package.json index e25a558..51c0052 100644 --- a/__tests__/bookshop/package.json +++ b/__tests__/bookshop/package.json @@ -1,5 +1,5 @@ { - "name": "bookshop", + "name": "@capire/bookshop-ord-sample", "version": "1.0.0", "description": "A simple CAP project.", "repository": "", diff --git a/__tests__/ord.test.js b/__tests__/ord.test.js index cde5605..003d77c 100644 --- a/__tests__/ord.test.js +++ b/__tests__/ord.test.js @@ -1,49 +1,86 @@ -const cds = require("@sap/cds"); const ord = require("../lib/ord"); -const path = require("path"); +const { join } = require("path"); + +// Mock the @sap/cds module +jest.mock("@sap/cds", () => { + const { join } = require("path"); + let originalCds = jest.requireActual("@sap/cds"); + originalCds.root = join(__dirname, "bookshop"); + return originalCds; +}); + +const cds = require("@sap/cds"); describe("Tests for default ORD document", () => { - let csn; + let csn; + + beforeAll(async () => { + csn = await cds.load(join(__dirname, "bookshop", "srv")); + }); - beforeAll(async () => { - csn = await cds.load(path.join(__dirname, "bookshop", "srv")); - }); + test("Successfully create ORD Documents with defaults", () => { + const document = ord(csn); + expect(document).toMatchSnapshot(); + }); + + describe("apiResources", () => { + // eslint-disable-next-line no-useless-escape + const PACKAGE_ID_REGEX = /^([a-z0-9]+(?:[.][a-z0-9]+)*):(package):([a-zA-Z0-9._\-]+):(v0|v[1-9][0-9]*)$/; + + let document; + + beforeAll(() => { + document = ord(csn); + }); + + test("partOfPackage values are valid ORD IDs ", () => { + for (const apiResource of document.apiResources) { + expect(apiResource.partOfPackage).toMatch(PACKAGE_ID_REGEX); + } + }); + + test("The partOfPackage references an existing package", () => { + for (const apiResource of document.apiResources) { + expect( + document.packages.find( + (pck) => pck.ordId === apiResource.partOfPackage + ) + ).toBeDefined(); + } + }); + }); - test("Successfully create ORD Documents with defaults", () => { - const document = ord(csn); - expect(document).toMatchSnapshot(); - }); + describe("eventResources", () => { + // eslint-disable-next-line no-useless-escape + const GROUP_ID_REGEX = /^([a-z0-9-]+(?:[.][a-z0-9-]+)*):([a-zA-Z0-9._\-/]+):([a-z0-9-]+(?:[.][a-z0-9-]+)*):(?[a-zA-Z0-9._\-/]+)$/; + let document; - describe("eventResources", () => { - const GROUP_ID_REGEX = /^([a-z0-9-]+(?:[.][a-z0-9-]+)*):([a-zA-Z0-9._\-/]+):([a-z0-9-]+(?:[.][a-z0-9-]+)*):(?[a-zA-Z0-9._\-/]+)$/ + beforeAll(() => { + document = ord(csn); + }); - let document; + test("Assigned to exactly one CDS Service group", () => { + for (const eventResource of document.eventResources) { + expect(eventResource.partOfGroups.length).toEqual(1); + } + }); - beforeAll(()=> { - document = ord(csn); - }) + test("The CDS Service Group ID includes the CDS Service identifier", () => { + for (const eventResource of document.eventResources) { + const [groupId] = eventResource.partOfGroups; + expect(groupId).toMatch(GROUP_ID_REGEX); - test("Assigned to excactly one CDS Service group", () => { - for (const eventResource of document.eventResources) { - expect(eventResource.partOfGroups.length).toEqual(1) - } + const match = GROUP_ID_REGEX.exec(groupId); + if (match && match.groups?.service) { + let service = match.groups?.service; + if (service.startsWith("undefined")) + service = service.replace("undefined.", ""); + const definition = csn.definitions[service]; + expect(definition).toBeDefined(); + expect(definition.kind).toEqual("service"); + } + } + }); }); - - test("The CDS Service Group ID includes the CDS Service identifier", () => { - for (const eventResource of document.eventResources) { - const [groupId] = eventResource.partOfGroups - expect(groupId).toMatch(GROUP_ID_REGEX) - - const match = GROUP_ID_REGEX.exec(groupId) - if (match && match.groups?.service) { - let service = match.groups?.service - if (service.startsWith("undefined")) service = service.replace("undefined.", "") - const definition = csn.definitions[service] - expect(definition).toBeDefined() - expect(definition.kind).toEqual("service") - } - } - }) - }) }); diff --git a/lib/ord.js b/lib/ord.js index 96b3997..b024fbc 100644 --- a/lib/ord.js +++ b/lib/ord.js @@ -1,4 +1,4 @@ -const path = require("path"); +const { join } = require("path"); const cds = require("@sap/cds"); const { exists } = cds.utils; const defaults = require("./defaults"); @@ -15,7 +15,7 @@ const { * @returns {Object} An object containing global variables. */ const fInitializeGlobal = (csn) => { - let packagejsonPath = path.join(cds.root,'package.json') + let packagejsonPath = join(cds.root,'package.json') let packageJson; if (exists(packagejsonPath)) { packageJson = require(packagejsonPath); @@ -28,13 +28,13 @@ const fInitializeGlobal = (csn) => { const aEvents = []; const aServices = []; const aODMEntity = []; - + const capNamespace = csn.namespace; // namespace variable value if present in cdsrc.json take it there or else from package.json //if cdsrc.json does not have applicationNamespace, then use just the namespace const namespace = cds.env["ord"]?.namespace || packageName.replace(/[^\w/]/g, "").replace(/\//, "."); const applicationNamespace = cds.env?.export?.asyncapi?.applicationNamespace; - + if (applicationNamespace && fGetNamespaceComponents(namespace) !== fGetNamespaceComponents(applicationNamespace)) { console.warn('ORD and AsyncAPI namespaces should be the same.'); } @@ -105,7 +105,7 @@ const fGetProducts = (global) => global.env?.products || defaults.products(globa /** * Retrieves the groups that services belongs to. * Gets list of groups from CDS runtime object. - * @param {Object} csn object + * @param {Object} csn object * @returns {Array} The groups array. */ const fGetGroups = (csn, global) => { @@ -119,7 +119,7 @@ const fGetGroups = (csn, global) => { * Hierarchy to check data: cdsrc.json > defaults * @returns {Array} The packages array. */ -const fGetPackages = (policyLevel,global) => global.env?.packages || (global.aEvents.length) ? defaults.packages(global.namespace,policyLevel,global.capNamespace) : defaults.packages(global.namespace,policyLevel,global.capNamespace).slice(0, 1) +const fGetPackages = (policyLevel,global) => global.env?.packages || (global.aEvents.length) ? defaults.packages(global.appName,policyLevel,global.capNamespace) : defaults.packages(global.appName,policyLevel,global.capNamespace).slice(0, 1) /** * Retrieves the API Resources