Skip to content

Commit 61984b5

Browse files
authored
Merge pull request #2316 from davidgamero/kind-integration-tests
update HeaderMiddleware types, export PatchStrategy with Integration Tests
2 parents 405d628 + 64ff97d commit 61984b5

File tree

9 files changed

+94
-24
lines changed

9 files changed

+94
-24
lines changed

.github/workflows/test.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,6 @@ jobs:
2626
- run: npm run lint
2727
- run: npm audit --audit-level=critical
2828
- run: npm run build-with-tests && npm run test-transpiled
29+
- name: Create k8s Kind Cluster
30+
uses: helm/kind-action@v1
31+
- run: npm run integration-test

examples/typescript/patch/patch-example.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { CoreV1Api, KubeConfig, setHeaderOptions, JsonPatch } from '@kubernetes/client-node';
1+
import { CoreV1Api, KubeConfig, setHeaderOptions, PatchStrategy } from '@kubernetes/client-node';
22

33
const kc = new KubeConfig();
44
kc.loadFromDefault();
@@ -28,7 +28,7 @@ try {
2828
namespace: 'default',
2929
body: patch,
3030
},
31-
setHeaderOptions('Content-Type', JsonPatch),
31+
setHeaderOptions('Content-Type', PatchStrategy.JsonPatch),
3232
);
3333

3434
console.log('Patched.');

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"watch": "tsc --watch",
2525
"test": "c8 mocha",
2626
"test-transpiled": "mocha --no-config dist",
27+
"integration-test": "tsx src/test/integration/index.ts",
2728
"prepare": "npm run build && husky",
2829
"prepack": "npm run build",
2930
"docs": "typedoc src/gen"

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export * from './metrics.js';
1616
export * from './object.js';
1717
export * from './health.js';
1818
export * from './middleware.js';
19+
export * from './patch.js';
1920
export { type ConfigOptions, type User, type Cluster, type Context } from './config_types.js';
2021

2122
// Export FetchError so that instanceof checks in user code will definitely use the same instance

src/middleware.ts

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,29 @@
1-
import type { RequestContext, ResponseContext, ConfigurationOptions, Middleware } from './gen/index.js';
2-
import { PromiseMiddleware } from './gen/middleware.js';
1+
import type {
2+
RequestContext,
3+
ResponseContext,
4+
ConfigurationOptions,
5+
ObservableMiddleware,
6+
} from './gen/index.js';
7+
import { of } from './gen/rxjsStub.js';
38

4-
// setHeaderMiddleware returns Middleware[] that sets a header value
5-
export function setHeaderMiddleware(key: string, value: string): Middleware[] {
6-
return [
7-
{
8-
pre: async (c: RequestContext) => {
9-
c.setHeaderParam(key, value);
10-
return c;
11-
},
12-
post: async (c: ResponseContext) => {
13-
return c;
14-
},
9+
export function setHeaderMiddleware(key: string, value: string): ObservableMiddleware {
10+
return {
11+
pre: (request: RequestContext) => {
12+
request.setHeaderParam(key, value);
13+
return of(request);
14+
},
15+
post: (response: ResponseContext) => {
16+
return of(response);
1517
},
16-
];
18+
};
1719
}
1820

1921
// Returns ConfigurationOptions that set a header
2022
export function setHeaderOptions(
2123
key: string,
2224
value: string,
23-
opt?: ConfigurationOptions<PromiseMiddleware>,
24-
): ConfigurationOptions<PromiseMiddleware> {
25+
opt?: ConfigurationOptions<ObservableMiddleware>,
26+
): ConfigurationOptions<ObservableMiddleware> {
2527
const newMiddlware = setHeaderMiddleware(key, value);
2628
const existingMiddlware = opt?.middleware || [];
2729
return {

src/middleware_test.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
import { RequestContext, ConfigurationOptions, HttpMethod } from './gen/index.js';
1+
import { RequestContext, ConfigurationOptions, HttpMethod, ObservableMiddleware } from './gen/index.js';
22
import { deepStrictEqual } from 'node:assert';
33
import { setHeaderMiddleware, setHeaderOptions } from './middleware.js';
4-
import { PromiseMiddleware } from './gen/middleware.js';
54

65
describe('Middleware', async () => {
76
describe('setHeaderMiddleware', async () => {
87
it('should set a header when it is blank', async () => {
98
const reqContext = new RequestContext('http://nowhere.com', HttpMethod.GET);
109
deepStrictEqual(reqContext.getHeaders(), {});
1110
const headerMiddleware = setHeaderMiddleware('test-key', 'test-value');
12-
const postMiddlewareRequest = await headerMiddleware[0].pre(reqContext);
11+
const postMiddlewareRequestObservable = await headerMiddleware.pre(reqContext);
12+
const postMiddlewareRequest = await postMiddlewareRequestObservable.toPromise();
1313
deepStrictEqual(postMiddlewareRequest.getHeaders(), { 'test-key': 'test-value' });
1414
});
1515

@@ -18,7 +18,7 @@ describe('Middleware', async () => {
1818
reqContext.setHeaderParam('test-key', 'wrong-value');
1919
deepStrictEqual(reqContext.getHeaders(), { 'test-key': 'wrong-value' });
2020
const headerMiddleware = setHeaderMiddleware('test-key', 'test-value');
21-
const postMiddlewareRequest = await headerMiddleware[0].pre(reqContext);
21+
const postMiddlewareRequest = await headerMiddleware.pre(reqContext).toPromise();
2222
deepStrictEqual(postMiddlewareRequest.getHeaders(), { 'test-key': 'test-value' });
2323
});
2424
});
@@ -27,7 +27,7 @@ describe('Middleware', async () => {
2727
it('should add middleware to set header with no input options arg', async () => {
2828
const reqContext = new RequestContext('http://nowhere.com', HttpMethod.GET);
2929
deepStrictEqual(reqContext.getHeaders(), {});
30-
const testConfigurationOptions: ConfigurationOptions<PromiseMiddleware> = {};
30+
const testConfigurationOptions: ConfigurationOptions<ObservableMiddleware> = {};
3131
const headerConfigurationOptions = setHeaderOptions(
3232
'test-key',
3333
'test-value',
@@ -39,7 +39,10 @@ describe('Middleware', async () => {
3939
) {
4040
throw new Error('missing middleware in ConfigurationOptions');
4141
}
42-
const postMiddlewareRequest = await headerConfigurationOptions.middleware[0].pre(reqContext);
42+
const postMiddlewareRequest = await headerConfigurationOptions.middleware[0]
43+
.pre(reqContext)
44+
.toPromise();
45+
4346
deepStrictEqual(postMiddlewareRequest.getHeaders(), { 'test-key': 'test-value' });
4447
});
4548
});

src/test/integration/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import patchNamespace from './patchNamespace.js';
2+
3+
console.log('Integration testing');
4+
5+
await patchNamespace();

src/test/integration/name.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/*
2+
* This function is used to generate a random name for the resources created in the tests.
3+
* This is to avoid conflicts with existing resources.
4+
*/
5+
export function generateName(name: string) {
6+
return name + '-' + Math.random().toString(36).substring(7);
7+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import assert from 'node:assert';
2+
import { PatchStrategy, CoreV1Api, KubeConfig, setHeaderOptions, V1Namespace } from '../../index.js';
3+
import { generateName } from './name.js';
4+
5+
export default async function patchNamespace() {
6+
const kc = new KubeConfig();
7+
kc.loadFromDefault();
8+
9+
const coreV1Client = kc.makeApiClient(CoreV1Api);
10+
let newNS = new V1Namespace();
11+
const testNSName = generateName('patch-ns');
12+
newNS.metadata = {
13+
name: testNSName,
14+
labels: {
15+
initialLabel: 'initialValue',
16+
},
17+
};
18+
console.log(`Creating namespace ${testNSName}`);
19+
await coreV1Client.createNamespace({ body: newNS });
20+
newNS = await coreV1Client.readNamespace({ name: testNSName });
21+
assert.strictEqual(newNS.metadata?.name, testNSName);
22+
assert.strictEqual(newNS.metadata?.labels?.initialLabel, 'initialValue');
23+
console.log('Namespace created with initial label.');
24+
25+
const patch = [
26+
{
27+
op: 'replace',
28+
path: '/metadata/labels',
29+
value: {
30+
foo: 'bar',
31+
},
32+
},
33+
];
34+
35+
console.log(`Patching namespace ${testNSName} to replace labels`);
36+
await coreV1Client.patchNamespace(
37+
{
38+
name: testNSName,
39+
body: patch,
40+
},
41+
setHeaderOptions('Content-Type', PatchStrategy.JsonPatch),
42+
);
43+
44+
const patchedNS = await coreV1Client.readNamespace({ name: testNSName });
45+
assert.strictEqual(patchedNS.metadata?.labels?.foo, 'bar');
46+
assert.strictEqual(patchedNS.metadata?.labels?.initialLabel, undefined);
47+
console.log('Namespace patched with new label.');
48+
}

0 commit comments

Comments
 (0)