Skip to content

Commit

Permalink
✨ (core) [NO-ISSUE]: Add a ListDeviceSessions use case (#303)
Browse files Browse the repository at this point in the history
  • Loading branch information
valpinkman authored Sep 20, 2024
2 parents f03c328 + f25bb8f commit 6f7db98
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/tender-rings-leave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ledgerhq/device-sdk-core": patch
---

Add ListDeviceSessions use case
4 changes: 2 additions & 2 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ _In case of visual features, please attach screenshots or video recordings to de
Pull Requests must pass the CI and be code reviewed. Set as Draft if the PR is not ready.

- [ ] **Covered by automatic tests.** <!-- if not, please explain. (Feature must be tested / Bugfix must bring non-regression) -->
- [ ] **Impact of the changes:** <!-- Please take some time to list the impact & what specific areas Quality Assurance (QA) should focus on -->
- [ ] **Changeset is provided** <!-- Please provide a changeset -->

- [ ] **Impact of the changes:** <!-- Please take some time to list the impact & what specific areas Quality Assurance (QA) should focus on -->
- ...
---

### 🧐 Checklist for the PR Reviewers
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/api/DeviceSdk.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ describe("DeviceSdk", () => {
it("should have sendCommand method", () => {
expect(sdk.sendCommand).toBeDefined();
});

it("should have listDeviceSessions method", () => {
expect(sdk.listDeviceSessions).toBeDefined();
});
});

describe("stubbed", () => {
Expand Down Expand Up @@ -100,6 +104,7 @@ describe("DeviceSdk", () => {
[usbDiTypes.GetConnectedDeviceUseCase],
[discoveryTypes.DisconnectUseCase],
[deviceSessionTypes.GetDeviceSessionStateUseCase],
[deviceSessionTypes.ListDeviceSessionsUseCase],
])("should have %p use case", (diSymbol) => {
const uc = sdk.container.get<StubUseCase>(diSymbol);
expect(uc).toBeInstanceOf(StubUseCase);
Expand Down
15 changes: 15 additions & 0 deletions packages/core/src/api/DeviceSdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ import { ConnectedDevice } from "@api/usb/model/ConnectedDevice";
import { configTypes } from "@internal/config/di/configTypes";
import { GetSdkVersionUseCase } from "@internal/config/use-case/GetSdkVersionUseCase";
import { deviceSessionTypes } from "@internal/device-session/di/deviceSessionTypes";
import { DeviceSession } from "@internal/device-session/model/DeviceSession";
import { GetDeviceSessionStateUseCase } from "@internal/device-session/use-case/GetDeviceSessionStateUseCase";
import { ListDeviceSessionsUseCase } from "@internal/device-session/use-case/ListDeviceSessionsUseCase";
import { discoveryTypes } from "@internal/discovery/di/discoveryTypes";
import { ConnectUseCase } from "@internal/discovery/use-case/ConnectUseCase";
import { DisconnectUseCase } from "@internal/discovery/use-case/DisconnectUseCase";
Expand Down Expand Up @@ -193,4 +195,17 @@ export class DeviceSdk {
)
.execute(args);
}

/**
* Lists all device sessions.
*
* @returns {DeviceSession[]} The list of device sessions.
*/
listDeviceSessions(): DeviceSession[] {
return this.container
.get<ListDeviceSessionsUseCase>(
deviceSessionTypes.ListDeviceSessionsUseCase,
)
.execute();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
} from "@internal/device-session/service/DefaultApduSenderService";
import { DefaultDeviceSessionService } from "@internal/device-session/service/DefaultDeviceSessionService";
import { GetDeviceSessionStateUseCase } from "@internal/device-session/use-case/GetDeviceSessionStateUseCase";
import { ListDeviceSessionsUseCase } from "@internal/device-session/use-case/ListDeviceSessionsUseCase";
import { loggerTypes } from "@internal/logger-publisher/di/loggerTypes";
import { LoggerPublisherService } from "@internal/logger-publisher/service/LoggerPublisherService";
import { StubUseCase } from "@root/src/di.stub";
Expand Down Expand Up @@ -67,8 +68,13 @@ export const deviceSessionModuleFactory = (
GetDeviceSessionStateUseCase,
);

bind(deviceSessionTypes.ListDeviceSessionsUseCase).to(
ListDeviceSessionsUseCase,
);

if (stub) {
rebind(deviceSessionTypes.GetDeviceSessionStateUseCase).to(StubUseCase);
rebind(deviceSessionTypes.ListDeviceSessionsUseCase).to(StubUseCase);
}
},
);
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export const deviceSessionTypes = {
ApduReceiverServiceFactory: Symbol.for("ApduReceiverServiceFactory"),
DeviceSessionService: Symbol.for("DeviceSessionService"),
GetDeviceSessionStateUseCase: Symbol.for("GetDeviceSessionStateUseCase"),
ListDeviceSessionsUseCase: Symbol.for("ListDeviceSessionsUseCase"),
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { deviceSessionStubBuilder } from "@internal/device-session/model/DeviceSession.stub";
import { DefaultDeviceSessionService } from "@internal/device-session/service/DefaultDeviceSessionService";
import { DeviceSessionService } from "@internal/device-session/service/DeviceSessionService";
import { DefaultLoggerPublisherService } from "@internal/logger-publisher/service/DefaultLoggerPublisherService";
import { LoggerPublisherService } from "@internal/logger-publisher/service/LoggerPublisherService";
import { AxiosManagerApiDataSource } from "@internal/manager-api/data/AxiosManagerApiDataSource";
import { ManagerApiDataSource } from "@internal/manager-api/data/ManagerApiDataSource";
import { DefaultManagerApiService } from "@internal/manager-api/service/DefaultManagerApiService";
import { ManagerApiService } from "@internal/manager-api/service/ManagerApiService";

import { ListDeviceSessionsUseCase } from "./ListDeviceSessionsUseCase";

let logger: LoggerPublisherService;
let sessionService: DeviceSessionService;
let managerApiDataSource: ManagerApiDataSource;
let managerApi: ManagerApiService;

describe("ListDeviceSessionsUseCase", () => {
beforeEach(() => {
logger = new DefaultLoggerPublisherService(
[],
"list-device-sessions-use-case-test",
);
managerApiDataSource = new AxiosManagerApiDataSource({
managerApiUrl: "http://fake.url",
});
managerApi = new DefaultManagerApiService(managerApiDataSource);
sessionService = new DefaultDeviceSessionService(() => logger);
});

it("should list all device sessions", () => {
// given
const deviceSession1 = deviceSessionStubBuilder(
{ id: "1" },
() => logger,
managerApi,
);
const deviceSession2 = deviceSessionStubBuilder(
{ id: "2" },
() => logger,
managerApi,
);
sessionService.addDeviceSession(deviceSession1);
sessionService.addDeviceSession(deviceSession2);
const useCase = new ListDeviceSessionsUseCase(sessionService, () => logger);

// when
const response = useCase.execute();

// then
expect(response).toStrictEqual([deviceSession1, deviceSession2]);
});

it("should return empty array if no device sessions", () => {
// given
const useCase = new ListDeviceSessionsUseCase(sessionService, () => logger);

// when
const response = useCase.execute();

// then
expect(response).toStrictEqual([]);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { inject, injectable } from "inversify";

import { deviceSessionTypes } from "@internal/device-session/di/deviceSessionTypes";
import { DeviceSession } from "@internal/device-session/model/DeviceSession";
import type { DeviceSessionService } from "@internal/device-session/service/DeviceSessionService";
import { loggerTypes } from "@internal/logger-publisher/di/loggerTypes";
import { LoggerPublisherService } from "@internal/logger-publisher/service/LoggerPublisherService";

/**
* List all device sessions.
*/
@injectable()
export class ListDeviceSessionsUseCase {
private readonly _sessionService: DeviceSessionService;
private readonly _logger: LoggerPublisherService;

constructor(
@inject(deviceSessionTypes.DeviceSessionService)
sessionService: DeviceSessionService,
@inject(loggerTypes.LoggerPublisherServiceFactory)
loggerFactory: (tag: string) => LoggerPublisherService,
) {
this._sessionService = sessionService;
this._logger = loggerFactory("ListDeviceSessionsUseCase");
}

execute(): DeviceSession[] {
this._logger.info("Listing device sessions");
return this._sessionService.getDeviceSessions();
}
}

0 comments on commit 6f7db98

Please sign in to comment.