Skip to content

Commit 138eb84

Browse files
authored
Merge pull request #108 from Hyperkid123/test-utils
Add react test utils package.
2 parents 260107d + 6940b54 commit 138eb84

File tree

13 files changed

+12466
-218
lines changed

13 files changed

+12466
-218
lines changed

config/jest.setup.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
import 'regenerator-runtime/runtime';
2+
import '@testing-library/jest-dom';

package-lock.json

Lines changed: 852 additions & 214 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@scalprum/core",
3-
"version": "0.6.0",
3+
"version": "0.6.1",
44
"description": "Includes core functions for scalprum scaffolding.",
55
"main": "dist/cjs/index.js",
66
"module": "dist/esm/index.js",

packages/core/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ const SHARED_SCOPE_NAME = 'default';
6161

6262
let scalprum: Scalprum | undefined;
6363

64-
const getModuleIdentifier = (scope: string, module: string) => `${scope}#${module}`;
64+
export const getModuleIdentifier = (scope: string, module: string) => `${scope}#${module}`;
6565

6666
export const getScalprum = () => {
6767
if (!scalprum) {

packages/react-core/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@scalprum/react-core",
3-
"version": "0.6.0",
3+
"version": "0.6.1",
44
"description": "React binding for @scalprum/core package.",
55
"main": "dist/cjs/index.js",
66
"module": "dist/esm/index.js",
@@ -27,7 +27,7 @@
2727
},
2828
"dependencies": {
2929
"@openshift/dynamic-plugin-sdk": "^4.0.0",
30-
"@scalprum/core": "^0.6.0",
30+
"@scalprum/core": "^0.6.1",
3131
"lodash": "^4.17.0"
3232
},
3333
"peerDependencies": {
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"name": "@scalprum/react-test-utils",
3+
"version": "0.0.5",
4+
"description": "Includes test utilities for scalprum scaffolding.",
5+
"main": "dist/cjs/index.js",
6+
"module": "dist/esm/index.js",
7+
"files": [
8+
"dist"
9+
],
10+
"typings": "dist/index.d.ts",
11+
"repository": "https://github.com/scalprum/scaffloding.git",
12+
"author": "Martin Marosi <marvusm.mmi@gmail.com>",
13+
"license": "Apache-2.0",
14+
"scripts": {
15+
"build": "npm run build:cjs && npm run build:esm && npm run build:typings",
16+
"build:esm": "tsc --module es2015 --target es5",
17+
"build:cjs": "tsc -p tsconfig.cjs.json",
18+
"build:typings": "node ../../scripts/create-typings.js",
19+
"start:esm": "npm run build:esm -- -w",
20+
"start:cjs": "npm run build:cjs -- -w"
21+
},
22+
"dependencies": {
23+
"@openshift/dynamic-plugin-sdk": "^4.0.0",
24+
"@scalprum/core": "^0.6.1",
25+
"@scalprum/react-core": "^0.6.1",
26+
"webpack": "^5.0.0",
27+
"whatwg-fetch": "^3.6.0"
28+
},
29+
"devDependencies": {
30+
"react": "^17.0.1 || ^18.0.0"
31+
}
32+
}
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/* eslint-disable no-var */
2+
import './overrides';
3+
import { PluginManifest } from '@openshift/dynamic-plugin-sdk';
4+
import { ScalprumProvider, ScalprumProviderProps, useScalprum } from '@scalprum/react-core';
5+
import { fetch as fetchPolyfill } from 'whatwg-fetch';
6+
import React, { useEffect } from 'react';
7+
import { AppsConfig, getModuleIdentifier, getScalprum } from '@scalprum/core';
8+
9+
type SharedScope = Record<string, Record<string, { loaded?: 1; get: () => Promise<unknown>; from: string; eager: boolean }>>;
10+
11+
declare global {
12+
var __webpack_share_scopes__: SharedScope;
13+
// var fetch: typeof fetchInternal;
14+
}
15+
16+
export function mockWebpackShareScope() {
17+
const __webpack_share_scopes__: SharedScope = {
18+
default: {},
19+
};
20+
globalThis.__webpack_share_scopes__ = __webpack_share_scopes__;
21+
}
22+
23+
export function mockFetch() {
24+
if (!globalThis.fetch) {
25+
globalThis.fetch = fetchPolyfill;
26+
}
27+
}
28+
29+
export function mockScalprum() {
30+
mockWebpackShareScope();
31+
mockFetch();
32+
}
33+
34+
type ModuleMock = {
35+
[importName: string]: React.ComponentType<any>;
36+
};
37+
38+
const ScalprumInitGate: React.ComponentType<
39+
React.PropsWithChildren<{
40+
moduleMock: ModuleMock;
41+
pluginManifest: PluginManifest;
42+
moduleName: string;
43+
}>
44+
> = ({ children, moduleMock, pluginManifest, moduleName }) => {
45+
const scalprum = useScalprum();
46+
const [mockReady, setMockReady] = React.useState(false);
47+
const { initialized } = scalprum;
48+
useEffect(() => {
49+
if (initialized && !mockReady) {
50+
const scalprum = getScalprum();
51+
scalprum.exposedModules[getModuleIdentifier(pluginManifest.name, moduleName)] = moduleMock;
52+
setMockReady(true);
53+
}
54+
}, [initialized, mockReady]);
55+
if (!initialized || !mockReady) {
56+
return null;
57+
}
58+
59+
return <>{children}</>;
60+
};
61+
62+
export const DEFAULT_MODULE_TEST_ID = 'default-module-test-id';
63+
64+
export function mockPluginData(
65+
{
66+
headers = new Headers(),
67+
url = 'http://localhost:3000/test-plugin/plugin-manifest.json',
68+
type = 'default',
69+
ok = true,
70+
status = 200,
71+
statusText = 'OK',
72+
pluginManifest = {
73+
baseURL: 'http://localhost:3000',
74+
extensions: [],
75+
loadScripts: [],
76+
name: 'test-plugin',
77+
version: '1.0.0',
78+
registrationMethod: 'custom',
79+
},
80+
module = 'ExposedModule',
81+
moduleMock = {
82+
default: () => <div data-testid={DEFAULT_MODULE_TEST_ID}>Default module</div>,
83+
},
84+
config = {
85+
[pluginManifest.name]: {
86+
name: pluginManifest.name,
87+
manifestLocation: url,
88+
},
89+
},
90+
}: {
91+
headers?: Headers;
92+
url?: string;
93+
type?: ResponseType;
94+
ok?: boolean;
95+
status?: number;
96+
statusText?: string;
97+
pluginManifest?: PluginManifest;
98+
module?: string;
99+
moduleMock?: ModuleMock;
100+
config?: AppsConfig;
101+
} = {},
102+
api: ScalprumProviderProps['api'] = {}
103+
) {
104+
const response: Response = {
105+
blob: () => Promise.resolve(new Blob()),
106+
formData: () => Promise.resolve(new FormData()),
107+
headers,
108+
ok,
109+
redirected: false,
110+
status,
111+
statusText,
112+
url,
113+
type,
114+
body: null,
115+
bodyUsed: false,
116+
arrayBuffer: () => {
117+
return Promise.resolve(new ArrayBuffer(0));
118+
},
119+
text() {
120+
return Promise.resolve(JSON.stringify(pluginManifest));
121+
},
122+
json: () => {
123+
return Promise.resolve(pluginManifest);
124+
},
125+
clone: () => response,
126+
};
127+
128+
const TestScalprumProvider: React.ComponentType<React.PropsWithChildren<{}>> = ({ children }) => {
129+
return (
130+
<ScalprumProvider config={config} api={api}>
131+
<ScalprumInitGate moduleName={module} pluginManifest={pluginManifest} moduleMock={moduleMock}>
132+
{children}
133+
</ScalprumInitGate>
134+
</ScalprumProvider>
135+
);
136+
};
137+
138+
return { response, TestScalprumProvider };
139+
}
140+
141+
mockScalprum();
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
declare module 'whatwg-fetch' {
2+
function fetch(input: RequestInfo | URL, init?: RequestInit | undefined): Promise<Response>;
3+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"extends": "./tsconfig.json",
3+
"compilerOptions": {
4+
"outDir": "./dist/cjs",
5+
"module": "commonjs"
6+
}
7+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"extends": "../../tsconfig.json",
3+
"compilerOptions": {
4+
"rootDir": "./src",
5+
"outDir": "./dist/esm",
6+
"declarationDir": "./dist/cjs",
7+
"esModuleInterop": true
8+
},
9+
"include": [
10+
"src/index.tsx",
11+
"./src/index.d.ts",
12+
],
13+
}

0 commit comments

Comments
 (0)