UNPKG

psn-api

Version:

A well-tested library that lets you get trophy, user, and game data from the PlayStation Network.

413 lines (348 loc) 12.1 kB
import nock from "nock"; import type { AccountDevicesResponse, AuthorizationPayload } from "../models"; import { getAccountDevices } from "./getAccountDevices"; import { USER_DMS_BASE_URL } from "./USER_BASE_URL"; const MOCK_ACCESS_TOKEN = "mockAccessToken"; const MOCK_ACCOUNT_ID = "1234567890123456789"; const INCLUDE_FIELDS = "device,systemData"; const PLATFORM = "PS5,PS4,PS3,PSVita"; const MOCK_ACTIVATION_PRIMARY = "PRIMARY"; const MOCK_ACTIVATION_PSN_GAME_V3 = "PSN_GAME_V3"; describe("Function: getAccountDevices", () => { afterEach(() => { nock.cleanAll(); }); it("is defined #sanity", () => { // ASSERT expect(getAccountDevices).toBeDefined(); }); it("retrieves the account devices for the current user", async () => { // ARRANGE const mockAuthorization: AuthorizationPayload = { accessToken: MOCK_ACCESS_TOKEN }; const mockResponse: AccountDevicesResponse = { accountId: MOCK_ACCOUNT_ID, accountDevices: [ { deviceId: "ps5-device-12345", deviceType: "PS5", activationType: MOCK_ACTIVATION_PRIMARY, activationDate: "2023-06-03T21:25:28.987Z", accountDeviceVector: "vector123abc" }, { deviceId: "ps4-device-67890", deviceType: "PS4", activationType: MOCK_ACTIVATION_PSN_GAME_V3, activationDate: "2023-01-15T10:30:00.000Z", accountDeviceVector: "vector456def" }, { deviceId: "psvita-device-11111", deviceType: "PSVita", activationType: MOCK_ACTIVATION_PSN_GAME_V3, activationDate: "2022-08-20T14:22:33.000Z", accountDeviceVector: "vector789ghi" } ] }; const baseUrlObj = new URL(USER_DMS_BASE_URL); const baseUrl = `${baseUrlObj.protocol}//${baseUrlObj.host}`; const basePath = baseUrlObj.pathname; nock(baseUrl) .get(`${basePath}/v1/devices/accounts/me`) .query({ includeFields: INCLUDE_FIELDS, platform: PLATFORM }) .reply(200, mockResponse); // ACT const response = await getAccountDevices(mockAuthorization); // ASSERT expect(response).toEqual(mockResponse); expect(response.accountDevices).toHaveLength(3); expect(response.accountDevices[0].deviceType).toBe("PS5"); expect(response.accountDevices[0].activationType).toBe(MOCK_ACTIVATION_PRIMARY); expect(response.accountDevices[1].deviceType).toBe("PS4"); expect(response.accountDevices[2].deviceType).toBe("PSVita"); }); it("returns empty devices list when user has no devices", async () => { // ARRANGE const mockAuthorization: AuthorizationPayload = { accessToken: MOCK_ACCESS_TOKEN }; const mockResponse: AccountDevicesResponse = { accountId: MOCK_ACCOUNT_ID, accountDevices: [] }; const baseUrlObj = new URL(USER_DMS_BASE_URL); const baseUrl = `${baseUrlObj.protocol}//${baseUrlObj.host}`; const basePath = baseUrlObj.pathname; nock(baseUrl) .get(`${basePath}/v1/devices/accounts/me`) .query({ includeFields: INCLUDE_FIELDS, platform: PLATFORM }) .reply(200, mockResponse); // ACT const response = await getAccountDevices(mockAuthorization); // ASSERT expect(response).toEqual(mockResponse); expect(response.accountDevices).toHaveLength(0); }); it("handles a single PS5 device correctly", async () => { // ARRANGE const mockAuthorization: AuthorizationPayload = { accessToken: MOCK_ACCESS_TOKEN }; const mockResponse: AccountDevicesResponse = { accountId: "9876543210987654321", accountDevices: [ { deviceId: "ps5-primary-device", deviceType: "PS5", activationType: MOCK_ACTIVATION_PRIMARY, activationDate: "2024-01-01T00:00:00.000Z", accountDeviceVector: "primaryvector123" } ] }; const baseUrlObj = new URL(USER_DMS_BASE_URL); const baseUrl = `${baseUrlObj.protocol}//${baseUrlObj.host}`; const basePath = baseUrlObj.pathname; nock(baseUrl) .get(`${basePath}/v1/devices/accounts/me`) .query({ includeFields: INCLUDE_FIELDS, platform: PLATFORM }) .reply(200, mockResponse); // ACT const response = await getAccountDevices(mockAuthorization); // ASSERT expect(response.accountDevices).toHaveLength(1); expect(response.accountDevices[0].deviceType).toBe("PS5"); expect(response.accountDevices[0].activationType).toBe(MOCK_ACTIVATION_PRIMARY); expect(response.accountDevices[0].deviceId).toBe("ps5-primary-device"); }); it("passes header overrides correctly", async () => { // ARRANGE const mockAuthorization: AuthorizationPayload = { accessToken: MOCK_ACCESS_TOKEN }; const mockOptions = { headerOverrides: { "Accept-Language": "ja-JP" } }; const mockResponse: AccountDevicesResponse = { accountId: MOCK_ACCOUNT_ID, accountDevices: [] }; const baseUrlObj = new URL(USER_DMS_BASE_URL); const baseUrl = `${baseUrlObj.protocol}//${baseUrlObj.host}`; const basePath = baseUrlObj.pathname; nock(baseUrl) .get(`${basePath}/v1/devices/accounts/me`) .query({ includeFields: INCLUDE_FIELDS, platform: PLATFORM }) .reply(200, mockResponse); // ACT const response = await getAccountDevices(mockAuthorization, mockOptions); // ASSERT expect(response).toEqual(mockResponse); }); it("throws an error if we receive a response containing an `error` object with message", async () => { // ARRANGE const mockAuthorization: AuthorizationPayload = { accessToken: MOCK_ACCESS_TOKEN }; const mockResponse = { error: { referenceId: "d71bd8ff-5f63-11ec-87da-d5dfd3bc6e67", code: 2_105_356, message: "Account devices not found" } }; const baseUrlObj = new URL(USER_DMS_BASE_URL); const baseUrl = `${baseUrlObj.protocol}//${baseUrlObj.host}`; const basePath = baseUrlObj.pathname; nock(baseUrl) .get(`${basePath}/v1/devices/accounts/me`) .query({ includeFields: INCLUDE_FIELDS, platform: PLATFORM }) .reply(200, mockResponse); // ASSERT await expect(getAccountDevices(mockAuthorization)).rejects.toThrow( "Account devices not found" ); }); it("throws an error with default message if error object has no message", async () => { // ARRANGE const mockAuthorization: AuthorizationPayload = { accessToken: MOCK_ACCESS_TOKEN }; const mockResponse = { error: { referenceId: "d71bd8ff-5f63-11ec-87da-d5dfd3bc6e67", code: 500 } }; const baseUrlObj = new URL(USER_DMS_BASE_URL); const baseUrl = `${baseUrlObj.protocol}//${baseUrlObj.host}`; const basePath = baseUrlObj.pathname; nock(baseUrl) .get(`${basePath}/v1/devices/accounts/me`) .query({ includeFields: INCLUDE_FIELDS, platform: PLATFORM }) .reply(200, mockResponse); // ASSERT await expect(getAccountDevices(mockAuthorization)).rejects.toThrow( "Unexpected Error" ); }); it("handles HTTP 404 response correctly", async () => { // ARRANGE const mockAuthorization: AuthorizationPayload = { accessToken: MOCK_ACCESS_TOKEN }; const baseUrlObj = new URL(USER_DMS_BASE_URL); const baseUrl = `${baseUrlObj.protocol}//${baseUrlObj.host}`; const basePath = baseUrlObj.pathname; nock(baseUrl) .get(`${basePath}/v1/devices/accounts/me`) .query({ includeFields: INCLUDE_FIELDS, platform: PLATFORM }) .reply(404, { error: { message: "User not found" } }); // ASSERT await expect(getAccountDevices(mockAuthorization)).rejects.toThrow(); }); it("handles HTTP 401 unauthorized response correctly", async () => { // ARRANGE const mockAuthorization: AuthorizationPayload = { accessToken: "invalidAccessToken" }; const baseUrlObj = new URL(USER_DMS_BASE_URL); const baseUrl = `${baseUrlObj.protocol}//${baseUrlObj.host}`; const basePath = baseUrlObj.pathname; nock(baseUrl) .get(`${basePath}/v1/devices/accounts/me`) .query({ includeFields: INCLUDE_FIELDS, platform: PLATFORM }) .reply(401, { error: { message: "Unauthorized" } }); // ASSERT await expect(getAccountDevices(mockAuthorization)).rejects.toThrow(); }); it("handles different device types correctly", async () => { // ARRANGE const mockAuthorization: AuthorizationPayload = { accessToken: MOCK_ACCESS_TOKEN }; const mockResponse: AccountDevicesResponse = { accountId: MOCK_ACCOUNT_ID, accountDevices: [ { deviceId: "ps3-device-001", deviceType: "PS3", activationType: MOCK_ACTIVATION_PSN_GAME_V3, activationDate: "2020-05-15T08:30:00.000Z", accountDeviceVector: "ps3vector001" }, { deviceId: "ps4-device-002", deviceType: "PS4", activationType: MOCK_ACTIVATION_PRIMARY, activationDate: "2021-03-20T12:45:30.000Z", accountDeviceVector: "ps4vector002" }, { deviceId: "ps5-device-003", deviceType: "PS5", activationType: MOCK_ACTIVATION_PRIMARY, activationDate: "2023-11-10T16:20:15.000Z", accountDeviceVector: "ps5vector003" }, { deviceId: "vita-device-004", deviceType: "PSVita", activationType: MOCK_ACTIVATION_PSN_GAME_V3, activationDate: "2019-12-01T09:15:45.000Z", accountDeviceVector: "vitavector004" } ] }; const baseUrlObj = new URL(USER_DMS_BASE_URL); const baseUrl = `${baseUrlObj.protocol}//${baseUrlObj.host}`; const basePath = baseUrlObj.pathname; nock(baseUrl) .get(`${basePath}/v1/devices/accounts/me`) .query({ includeFields: INCLUDE_FIELDS, platform: PLATFORM }) .reply(200, mockResponse); // ACT const response = await getAccountDevices(mockAuthorization); // ASSERT expect(response.accountDevices).toHaveLength(4); const ps3Device = response.accountDevices.find( (d) => d.deviceType === "PS3" ); const ps4Device = response.accountDevices.find( (d) => d.deviceType === "PS4" ); const ps5Device = response.accountDevices.find( (d) => d.deviceType === "PS5" ); const vitaDevice = response.accountDevices.find( (d) => d.deviceType === "PSVita" ); expect(ps3Device).toBeDefined(); expect(ps3Device?.activationType).toBe(MOCK_ACTIVATION_PSN_GAME_V3); expect(ps4Device).toBeDefined(); expect(ps4Device?.activationType).toBe(MOCK_ACTIVATION_PRIMARY); expect(ps5Device).toBeDefined(); expect(ps5Device?.activationType).toBe(MOCK_ACTIVATION_PRIMARY); expect(vitaDevice).toBeDefined(); expect(vitaDevice?.activationType).toBe(MOCK_ACTIVATION_PSN_GAME_V3); }); it("verifies correct API endpoint and query parameters are used", async () => { // ARRANGE const mockAuthorization: AuthorizationPayload = { accessToken: MOCK_ACCESS_TOKEN }; const mockResponse: AccountDevicesResponse = { accountId: MOCK_ACCOUNT_ID, accountDevices: [] }; const baseUrlObj = new URL(USER_DMS_BASE_URL); const baseUrl = `${baseUrlObj.protocol}//${baseUrlObj.host}`; const basePath = baseUrlObj.pathname; // Verify exact query parameters const scope = nock(baseUrl) .get(`${basePath}/v1/devices/accounts/me`) .query((query) => { return ( query.includeFields === INCLUDE_FIELDS && query.platform === PLATFORM ); }) .reply(200, mockResponse); // ACT await getAccountDevices(mockAuthorization); // ASSERT expect(scope.isDone()).toBe(true); }); });