forked from janus-idp/backstage-showcase
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add
scalprum
backend plugin. (janus-idp#599)
* feat: add a `scalprum` backend plugin. This plugins depends on the `backend-plugin-manager` and provides access to the scalprum defintinions, and the plugin assets of the dynamic frontend plugins installed in the dynamic plugins root folder. Signed-off-by: David Festal <dfestal@redhat.com> * Add changeset Signed-off-by: David Festal <dfestal@redhat.com> --------- Signed-off-by: David Festal <dfestal@redhat.com>
- Loading branch information
1 parent
2671dba
commit 4af2b85
Showing
13 changed files
with
515 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
--- | ||
'@internal/plugin-scalprum-backend': patch | ||
'backend': patch | ||
--- | ||
|
||
Add a `scalprum` backend plugin. | ||
|
||
This plugin depends on the `backend-plugin-manager` and | ||
provides access to the scalprum defintinions, | ||
as well as the plugin assets, | ||
of the dynamic frontend plugins which are | ||
installed in the dynamic plugins root folder. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ | |
**/dist | ||
**/node_modules | ||
plugins | ||
!plugins/scalprum-backend | ||
*.local.yaml | ||
coverage | ||
dist-types | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# scalprum | ||
|
||
Welcome to the scalprum backend plugin! | ||
|
||
This plugin depends on the `backend-plugin-manager` and | ||
provides access to the scalprum manifest, as well as plugin assets, | ||
of every dynamic frontend plugin installed in the dynamic plugins root folder. | ||
|
||
It is used by the dynamic frontend plugin support in the frontend showcase application. | ||
|
||
## Getting started | ||
|
||
Your plugin has been added to the backend app in this repository, meaning you'll be able to access it by running `yarn | ||
start-backend` in the root directory, and then navigating to [/api/scalprum](http://localhost:7007/api/scalprum). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
{ | ||
"name": "@internal/plugin-scalprum-backend", | ||
"version": "0.1.0", | ||
"main": "src/index.ts", | ||
"types": "src/index.ts", | ||
"license": "Apache-2.0", | ||
"private": true, | ||
"publishConfig": { | ||
"access": "public", | ||
"main": "dist/index.cjs.js", | ||
"types": "dist/index.d.ts" | ||
}, | ||
"backstage": { | ||
"role": "backend-plugin" | ||
}, | ||
"scripts": { | ||
"start": "backstage-cli package start", | ||
"build": "backstage-cli package build", | ||
"lint": "backstage-cli package lint", | ||
"test": "backstage-cli package test", | ||
"clean": "backstage-cli package clean", | ||
"prepack": "backstage-cli package prepack", | ||
"postpack": "backstage-cli package postpack" | ||
}, | ||
"dependencies": { | ||
"@backstage/backend-common": "^0.19.7", | ||
"@backstage/backend-plugin-api": "^0.6.5", | ||
"@backstage/backend-plugin-manager": "npm:@janus-idp/backend-plugin-manager@0.0.5-janus.0", | ||
"@backstage/config": "^1.1.0", | ||
"@types/express": "*", | ||
"express": "^4.17.1", | ||
"express-promise-router": "^4.1.0", | ||
"node-fetch": "^2.6.7", | ||
"winston": "^3.2.1" | ||
}, | ||
"devDependencies": { | ||
"@backstage/cli": "0.22.13", | ||
"@types/supertest": "^2.0.12", | ||
"@types/mock-fs": "^4.13.0", | ||
"mock-fs": "^5.1.10", | ||
"msw": "^1.0.0", | ||
"supertest": "^6.2.4" | ||
}, | ||
"files": [ | ||
"dist" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './service/router'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,212 @@ | ||
import express, { Router } from 'express'; | ||
import request from 'supertest'; | ||
import url from 'url'; | ||
import path from 'path'; | ||
import { createRouter } from './router'; | ||
import { | ||
PluginManager, | ||
ScannedPluginManifest, | ||
ScannedPluginPackage, | ||
} from '@backstage/backend-plugin-manager'; | ||
import mockFs from 'mock-fs'; | ||
import { randomUUID } from 'crypto'; | ||
import { LoggerService } from '@backstage/backend-plugin-api'; | ||
|
||
describe('createRouter', () => { | ||
let app: express.Express; | ||
let router: Router; | ||
|
||
beforeEach(() => { | ||
app = express(); | ||
}); | ||
|
||
afterEach(() => { | ||
jest.resetAllMocks(); | ||
mockFs.restore(); | ||
app.delete('scalprum'); | ||
}); | ||
|
||
type TestCase = { | ||
name: string; | ||
packageManifest: ScannedPluginManifest & { scalprum?: { name: string } }; | ||
pluginExternalBaseURL: string; | ||
distScalprumDir?: any; | ||
testedPluginsURL: string; | ||
expectedPluginsStatusCode: number; | ||
expectedPluginsBody: any; | ||
testedManifestURL?: string; | ||
expectedManifestStatusCode?: number; | ||
expectedManifestBody?: any; | ||
expectedWarning?: string; | ||
}; | ||
|
||
it.each<TestCase>([ | ||
{ | ||
name: 'should add the frontend plugin in the scalprum plugin map', | ||
packageManifest: { | ||
name: 'frontend-dynamic-plugin-test', | ||
version: '0.0.0', | ||
backstage: { | ||
role: 'frontend-plugin', | ||
}, | ||
main: 'dist/index.cjs.js', | ||
scalprum: { | ||
name: 'scalprum-plugin', | ||
}, | ||
}, | ||
pluginExternalBaseURL: 'http://localhost:3000', | ||
distScalprumDir: mockFs.directory({ | ||
items: { | ||
'plugin-manifest.json': mockFs.file({ | ||
content: JSON.stringify({ | ||
name: 'scalprum-plugin', | ||
anotherField: 'anotherValue', | ||
}), | ||
}), | ||
}, | ||
}), | ||
testedPluginsURL: '/scalprum/plugins', | ||
expectedPluginsStatusCode: 200, | ||
expectedPluginsBody: { | ||
'scalprum-plugin': { | ||
manifestLocation: | ||
'http://localhost:3000/scalprum-plugin/plugin-manifest.json', | ||
name: 'scalprum-plugin', | ||
}, | ||
}, | ||
testedManifestURL: '/scalprum/scalprum-plugin/plugin-manifest.json', | ||
expectedManifestStatusCode: 200, | ||
expectedManifestBody: { | ||
name: 'scalprum-plugin', | ||
anotherField: 'anotherValue', | ||
}, | ||
}, | ||
{ | ||
name: 'should skip a frontend plugin when the dist-scalprum sub-folder is missing', | ||
packageManifest: { | ||
name: 'frontend-dynamic-plugin-test', | ||
version: '0.0.0', | ||
backstage: { | ||
role: 'frontend-plugin', | ||
}, | ||
main: 'dist/index.cjs.js', | ||
scalprum: { | ||
name: 'scalprum-plugin', | ||
}, | ||
}, | ||
pluginExternalBaseURL: 'http://localhost:3000', | ||
testedPluginsURL: '/scalprum/plugins', | ||
expectedPluginsStatusCode: 200, | ||
expectedPluginsBody: {}, | ||
expectedWarning: | ||
"Could not find 'scalprum-dist' folder for plugin frontend-dynamic-plugin-test@0.0.0", | ||
}, | ||
{ | ||
name: 'should skip a frontend plugin when the scalprum entry is missing', | ||
packageManifest: { | ||
name: 'frontend-dynamic-plugin-test', | ||
version: '0.0.0', | ||
backstage: { | ||
role: 'frontend-plugin', | ||
}, | ||
main: 'dist/index.cjs.js', | ||
}, | ||
pluginExternalBaseURL: 'http://localhost:3000', | ||
distScalprumDir: mockFs.directory({}), | ||
testedPluginsURL: '/scalprum/plugins', | ||
expectedPluginsStatusCode: 200, | ||
expectedPluginsBody: {}, | ||
expectedWarning: | ||
'Could not find scalprum entry for plugin frontend-dynamic-plugin-test@0.0.0', | ||
}, | ||
{ | ||
name: 'should skip a frontend plugin when the dist-scalprum/plugin-manifest.json file is missing', | ||
packageManifest: { | ||
name: 'frontend-dynamic-plugin-test', | ||
version: '0.0.0', | ||
backstage: { | ||
role: 'frontend-plugin', | ||
}, | ||
main: 'dist/index.cjs.js', | ||
scalprum: { | ||
name: 'scalprum-plugin', | ||
}, | ||
}, | ||
pluginExternalBaseURL: 'http://localhost:3000', | ||
distScalprumDir: mockFs.directory({}), | ||
testedPluginsURL: '/scalprum/plugins', | ||
expectedPluginsStatusCode: 200, | ||
expectedPluginsBody: {}, | ||
expectedWarning: | ||
"Could not find 'dist-scalprum/plugin-manifest.json' for plugin frontend-dynamic-plugin-test@0.0.0", | ||
}, | ||
])('$name', async (tc: TestCase): Promise<void> => { | ||
const plugin: ScannedPluginPackage = { | ||
location: url.pathToFileURL( | ||
path.resolve(`/node_modules/jest-tests/${randomUUID()}`), | ||
), | ||
manifest: tc.packageManifest, | ||
}; | ||
|
||
const mockedFiles: { [key: string]: any } = {}; | ||
|
||
if (tc.distScalprumDir) { | ||
mockedFiles[ | ||
path.join(url.fileURLToPath(plugin.location), 'dist-scalprum') | ||
] = tc.distScalprumDir; | ||
} | ||
|
||
mockFs(mockedFiles); | ||
|
||
const warn = jest.fn(); | ||
const logger: LoggerService = { | ||
error: jest.fn(), | ||
warn: warn, | ||
info: jest.fn(), | ||
debug: jest.fn(), | ||
child: jest.fn(), | ||
}; | ||
|
||
const pluginManager = new (PluginManager as any)(logger, [plugin], { | ||
logger, | ||
async bootstrap(_: string, __: string[]): Promise<void> {}, | ||
load: async (packagePath: string) => | ||
await import(/* webpackIgnore: true */ packagePath), | ||
}); | ||
pluginManager.plugins.push(...(await pluginManager.loadPlugins())); | ||
|
||
const getBaseUrl = jest.fn().mockReturnValue('should-not-be-used'); | ||
const getExternalBaseUrl = jest | ||
.fn() | ||
.mockReturnValue(tc.pluginExternalBaseURL); | ||
|
||
router = await createRouter({ | ||
logger: logger, | ||
discovery: { | ||
getBaseUrl, | ||
getExternalBaseUrl, | ||
}, | ||
pluginManager, | ||
}); | ||
|
||
app.use('/scalprum', router); | ||
const response = await request(app).get(tc.testedPluginsURL); | ||
expect(response.status).toEqual(tc.expectedPluginsStatusCode); | ||
expect(response.body).toEqual(tc.expectedPluginsBody); | ||
|
||
let manifestStatusCode: number | undefined; | ||
let manifestBody: any | undefined; | ||
if (tc.testedManifestURL) { | ||
const manifestResponse = await request(app).get(tc.testedManifestURL); | ||
manifestStatusCode = manifestResponse.status; | ||
manifestBody = manifestResponse.body; | ||
} | ||
expect(manifestStatusCode).toEqual(tc.expectedManifestStatusCode); | ||
expect(manifestBody).toEqual(tc.expectedManifestBody); | ||
|
||
if (tc.expectedWarning) { | ||
// eslint-disable-next-line jest/no-conditional-expect | ||
expect(warn).toHaveBeenCalledWith(tc.expectedWarning); | ||
} | ||
}); | ||
}); |
Oops, something went wrong.