diff --git a/web/src/services/connectionsService.test.ts b/web/src/services/connectionsService.test.ts new file mode 100644 index 00000000..5461a0a0 --- /dev/null +++ b/web/src/services/connectionsService.test.ts @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, it, vi } from 'vitest'; + +vi.mock('../config', () => ({ + USE_MOCK: true, + API_BASE_URL: '/api', +})); + +import { listConnections } from './connectionsService'; + +describe('connectionsService mock connections', () => { + it('returns defensive copies after applying filters', async () => { + const connections = await listConnections({ clusterId: 'ns-prod', type: 'Consumer' }); + const originalClientId = connections[0].clientId; + const originalAddress = connections[0].address; + + connections[0].clientId = 'mutated-client'; + connections[0].address = '127.0.0.1:8081'; + + const fresh = await listConnections({ clusterId: 'ns-prod', type: 'Consumer' }); + + expect(fresh[0].clientId).toBe(originalClientId); + expect(fresh[0].address).toBe(originalAddress); + expect(fresh[0]).not.toBe(connections[0]); + expect(fresh.every((connection) => connection.clusterName === 'ns-prod')).toBe(true); + expect(fresh.every((connection) => connection.type === 'Consumer')).toBe(true); + }); +}); diff --git a/web/src/services/connectionsService.ts b/web/src/services/connectionsService.ts index b773cea9..d29b58a0 100644 --- a/web/src/services/connectionsService.ts +++ b/web/src/services/connectionsService.ts @@ -3,13 +3,17 @@ import * as connApi from '../api/connections'; import type { ClientConnection, ClientConnectionQuery } from '../api/connections'; import { mockClients } from '../mock/clients'; +function copyConnection(connection: ClientConnection): ClientConnection { + return { ...connection }; +} + export async function listConnections(params?: ClientConnectionQuery): Promise { if (USE_MOCK) { let result = [...mockClients]; if (params?.clusterId) result = result.filter((connection) => connection.clusterName === params.clusterId); if (params?.type) result = result.filter((c) => c.type === params.type); - return result as unknown as ClientConnection[]; + return (result as unknown as ClientConnection[]).map(copyConnection); } return connApi.listConnections(params); }