Cp add device tests (#2264)

This commit is contained in:
Łukasz Kowalczyk
2025-01-09 19:14:55 +01:00
committed by GitHub
parent 44e1bdb77b
commit 66977831bc
19 changed files with 300 additions and 9 deletions

View File

@@ -0,0 +1,12 @@
{
"presets": [
[
"@nx/react/babel",
{
"runtime": "automatic",
"useBuiltIns": "usage"
}
]
],
"plugins": []
}

View File

@@ -0,0 +1,18 @@
{
"extends": ["../../.eslintrc.js"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}

View File

@@ -0,0 +1,7 @@
# api-devices-testing
This library was generated with [Nx](https://nx.dev).
## Running unit tests
Run `nx test api-devices-testing` to execute the unit tests via [Jest](https://jestjs.io).

View File

@@ -0,0 +1,12 @@
/* eslint-disable */
export default {
displayName: "api-devices-testing",
preset: "../../jest.preset.js",
transform: {
"^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "@nx/react/plugins/jest",
"^.+\\.[tj]sx?$": ["babel-jest", { presets: ["@nx/react/babel"] }],
},
moduleFileExtensions: ["ts", "tsx", "js", "jsx"],
coverageDirectory: "../../coverage/libs/api-devices-testing",
maxWorkers: 1,
}

View File

@@ -0,0 +1,20 @@
{
"name": "api-devices-testing",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/api-devices-testing/src",
"projectType": "library",
"tags": [],
"targets": {
"lint": {
"executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"]
},
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "libs/api-devices-testing/jest.config.ts"
}
}
}
}

View File

@@ -0,0 +1,50 @@
/**
* Copyright (c) Mudita sp. z o.o. All rights reserved.
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
*/
import { DeviceProtocol } from "device-protocol/feature"
import { setKompaktConnection } from "./helpers/set-connection"
import { APIConfigService } from "device/feature"
jest.mock("shared/utils", () => {
return { callRenderer: () => {} }
})
jest.mock("Core/device-manager/services/usb-devices/usb-devices.helper", () => {
return { getUsbDevices: () => {} }
})
jest.mock("electron-better-ipc", () => {
return {
ipcMain: {
emit: () => {},
},
}
})
describe("API configuration", () => {
let deviceProtocol: DeviceProtocol | undefined = undefined
beforeEach(async () => {
deviceProtocol = await setKompaktConnection()
})
afterEach(async () => {
await deviceProtocol?.activeDevice?.disconnect()
}, 10000)
it("should receive API configuration", async () => {
expect(deviceProtocol?.devices).toHaveLength(1)
if (deviceProtocol === undefined) {
return
}
deviceProtocol.setActiveDevice(deviceProtocol.devices[0].id)
const apiConfigService = new APIConfigService(deviceProtocol)
const result = await apiConfigService.getAPIConfig()
expect(result.ok).toBeTruthy()
})
})

View File

@@ -0,0 +1,49 @@
/**
* Copyright (c) Mudita sp. z o.o. All rights reserved.
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
*/
import {
DeviceProtocol,
DeviceResolverService,
SerialPortService,
} from "device-protocol/feature"
import { EventEmitter } from "events"
jest.mock("shared/utils", () => {
return { callRenderer: () => {} }
})
jest.mock("Core/device-manager/services/usb-devices/usb-devices.helper", () => {
return { getUsbDevices: () => {} }
})
describe("Connection", () => {
it.each([{ vendorId: "0e8d", productId: "200a" }])(
"should connect successfully",
async ({ vendorId, productId }) => {
const eventEmitter = new EventEmitter()
const deviceProtocol = new DeviceProtocol(
new SerialPortService(),
new DeviceResolverService(),
eventEmitter
)
expect(deviceProtocol.devices).toHaveLength(0)
const attachedDevice = (await deviceProtocol.getAttachedDevices()).find(
(port) => {
return port.vendorId === vendorId && port.productId === productId
}
)
expect(attachedDevice).toBeTruthy()
if (attachedDevice === undefined) {
return
}
await deviceProtocol.addDevice(attachedDevice)
expect(deviceProtocol.devices).toHaveLength(1)
await deviceProtocol.activeDevice?.disconnect()
}
)
})

View File

@@ -0,0 +1,38 @@
/**
* Copyright (c) Mudita sp. z o.o. All rights reserved.
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
*/
import {
DeviceProtocol,
DeviceResolverService,
SerialPortService,
} from "device-protocol/feature"
import { EventEmitter } from "events"
export const setConnection = async (vendorId: string, productId: string) => {
const eventEmitter = new EventEmitter()
const deviceProtocol = new DeviceProtocol(
new SerialPortService(),
new DeviceResolverService(),
eventEmitter
)
const attachedDevice = (await deviceProtocol.getAttachedDevices()).find(
(port) => {
return port.vendorId === vendorId && port.productId === productId
}
)
if (attachedDevice === undefined) {
return
}
await deviceProtocol.addDevice(attachedDevice)
return deviceProtocol
}
export const setKompaktConnection = () => {
return setConnection("0e8d", "200a")
}

View File

@@ -0,0 +1,20 @@
{
"compilerOptions": {
"jsx": "react-jsx",
"allowJs": false,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
},
{
"path": "./tsconfig.spec.json"
}
],
"extends": "../../tsconfig.base.json"
}

View File

@@ -0,0 +1,24 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"types": [
"node",
"@nx/react/typings/cssmodule.d.ts",
"@nx/react/typings/image.d.ts"
]
},
"exclude": [
"jest.config.ts",
"src/**/*.spec.ts",
"src/**/*.test.ts",
"src/**/*.spec.tsx",
"src/**/*.test.tsx",
"src/**/*.spec.js",
"src/**/*.test.js",
"src/**/*.spec.jsx",
"src/**/*.test.jsx"
],
"include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]
}

View File

@@ -0,0 +1,20 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": [
"jest.config.ts",
"src/**/*.test.ts",
"src/**/*.spec.ts",
"src/**/*.test.tsx",
"src/**/*.spec.tsx",
"src/**/*.test.js",
"src/**/*.spec.js",
"src/**/*.test.jsx",
"src/**/*.spec.jsx",
"src/**/*.d.ts"
]
}

View File

@@ -41,6 +41,10 @@ export abstract class BaseDevice {
abstract connect(): Promise<ResultObject<undefined>>
public disconnect(): Promise<unknown> {
return Promise.resolve()
}
abstract request(config: unknown): Promise<unknown>
private generateDeviceIdBySerialNumber = (

View File

@@ -34,6 +34,7 @@ export abstract class BaseAdapter<
return new Promise((resolve) => {
const serialPort = new SerialPort(this.path, (error) => {
if (error) {
console.error(error)
resolve(
Result.failed(
new AppError(DeviceError.Initialization, error.message)

View File

@@ -106,7 +106,6 @@ export class DeviceProtocol {
}
public async addDevice(port: PortInfo): Promise<void> {
console.log("===== addDevice =====")
await this.mutex.runExclusive(async () => {
await this.addDeviceTask(port)
})

View File

@@ -44,6 +44,7 @@ export class SerialPortDeviceAPIAdapter {
return new Promise((resolve) => {
const serialPort = new SerialPort(this.path, (error) => {
if (error) {
console.error(error)
resolve(
Result.failed(
new AppError(DeviceError.Initialization, error.message)
@@ -58,6 +59,17 @@ export class SerialPortDeviceAPIAdapter {
})
}
public closeConnection() {
return new Promise((resolve) => {
if (this.serialPort) {
this.serialPort.close((error) => {
resolve(undefined)
})
}
resolve(undefined)
})
}
public async request(config: APIRequestData) {
if (this.serialPort === undefined) {
return Result.failed(
@@ -222,7 +234,6 @@ export class SerialPortDeviceAPIAdapter {
)
}
})
this.serialPort.on("close", () => {
callRenderer(
ApiSerialPortToRendererEvents.Closed,

View File

@@ -30,6 +30,10 @@ export class APIDevice extends BaseDevice {
return this.adapter.connect()
}
override disconnect() {
return this.adapter.closeConnection()
}
public request<R, T extends APIEndpointType>(
config: APIRequestWithPayload<T>
) {

10
nx.json
View File

@@ -1,4 +1,9 @@
{
"pluginsConfig": {
"@nx/js": {
"analyzeSourceFiles": true
}
},
"extends": "nx/presets/npm.json",
"$schema": "./node_modules/nx/schemas/nx-schema.json",
"tasksRunnerOptions": {
@@ -39,10 +44,5 @@
}
}
}
},
"pluginsConfig": {
"@nx/js": {
"analyzeSourceFiles": true
}
}
}

View File

@@ -21,7 +21,7 @@
"app:translations:sync": "nx translations:sync mudita-center",
"test": "npm run test:nx && npm run test:core",
"test:core": "cross-env TZ=UTC jest --config=jest/jest.config.js",
"test:nx": "nx run-many --target=test",
"test:nx": "nx run-many --target=test --exclude api-devices-testing",
"lint": "npm run lint:js && npm run lint:css",
"lint:css": "cross-env stylelint '{libs,apps/mudita-center/src}/**/*.{ts,tsx}'",
"lint:fix": "npm run lint:js -- --fix",
@@ -37,7 +37,8 @@
"e2e:test:cicd:standalone": "xvfb-run --auto-servernum --server-args='-screen 0 1024x768x24' nx e2e:test:cicd:standalone mudita-center-e2e",
"e2e:test:cicd:mock": "xvfb-run --auto-servernum --server-args='-screen 0 1024x768x24' nx e2e:test:cicd:mock mudita-center-e2e",
"test-file:generate-and-push": "ts-node scripts/manage-test-files/generate-and-push-test-files.ts",
"test-file:clear": "ts-node scripts/manage-test-files/clear-test-files.ts"
"test-file:clear": "ts-node scripts/manage-test-files/clear-test-files.ts",
"api-device-testing": "npx nx run api-devices-testing:test"
},
"repository": {
"type": "git",

View File

@@ -34,6 +34,7 @@
"active-device-registry/models": [
"libs/active-device-registry/models/src/index.ts"
],
"api-devices-testing": ["libs/api-devices-testing/src/index.ts"],
"core-device/feature": ["libs/core-device/feature/src/index.ts"],
"core-device/models": ["libs/core-device/models/src/index.ts"],
"device-manager/feature": ["libs/device-manager/feature/src/index.ts"],