From 32ab4ff98928d49eeea38d2dba6c083f999a103a Mon Sep 17 00:00:00 2001 From: MytsV Date: Wed, 21 Aug 2024 16:15:32 +0300 Subject: [PATCH] Reformat the tests with prettier --- .../list-account-rse-quotas-usecase.ts | 4 +- test/api/account/get-account-info.test.ts | 71 +- test/api/account/switch.test.ts | 69 +- test/api/auth/login-page-config.test.ts | 80 ++- test/api/auth/session.test.ts | 56 +- test/api/auth/userpass.test.ts | 85 +-- test/api/auth/x509-session.test.ts | 118 ++-- test/api/did/did-keyvaluepairs.test.ts | 82 +-- test/api/did/did-meta.test.ts | 156 ++--- test/api/did/list-did-contents.test.ts | 109 +-- test/api/did/list-did-parents.test.ts | 115 ++-- test/api/did/list-did-rules.test.ts | 148 +++-- test/api/did/list-dids-stream-error.test.ts | 137 ++-- test/api/did/list-dids.test.ts | 135 ++-- test/api/get-site-header.test.ts | 62 +- test/api/jest.api.setup.ts | 12 +- .../api/replica/list-dataset-replicas.test.ts | 131 ++-- test/api/replica/list-file-replicas.test.ts | 112 ++-- test/api/rse/get-rse-attributes.test.ts | 78 +-- test/api/rse/get-rse-protocols.test.ts | 283 ++++---- test/api/rse/get-rse.test.ts | 44 +- test/api/rse/list-all-rses.test.ts | 142 ++-- test/api/rse/list-rses.test.ts | 102 ++- test/api/rule/list-account-rse-quotas.test.ts | 167 +++-- .../list-subscription-rule-states.test.ts | 91 +-- .../subscription/list-subscription.test.ts | 162 +++-- test/api/subscription/subscription.test.ts | 75 ++- test/clean-design.test.ts | 51 +- test/component/CreateRule.test.tsx | 98 +-- test/component/ListDID.test.tsx | 142 ++-- test/component/Login.test.tsx | 459 ++++++------- test/component/LoginX509.test.tsx | 166 +++-- test/component/PageRule.test.tsx | 79 ++- test/component/jest.component.setup.ts | 21 +- test/fixtures/http-fixtures.ts | 35 +- test/fixtures/multi-vo-fixtures.ts | 27 +- test/fixtures/oidc-provider-config.ts | 125 ++-- test/fixtures/rse-fixtures.ts | 619 +++++++++++++++++- test/fixtures/rucio-server.ts | 72 +- test/fixtures/stream-test-utils.ts | 18 +- test/fixtures/table-fixtures.ts | 222 ++++--- test/fixtures/widget-fixtures.ts | 18 +- test/gateway/account/account-gateway.test.ts | 78 +-- test/gateway/account/get-account-info.test.ts | 69 +- .../account/get-account-limits.test.ts | 59 +- .../account/list-account-rse-usage.test.ts | 108 ++- .../did/did-gateway-add-attach-status.test.ts | 122 ++-- .../did/did-gateway-create-did-sample.test.ts | 43 +- .../did/did-gateway-keyvaluepairs.test.ts | 44 +- .../did/did-gateway-list-did-contents.test.ts | 85 ++- ...d-gateway-list-did-parent-endpoint.test.ts | 91 +-- .../did-gateway-list-rules-endpoint.test.ts | 153 +++-- .../did/did-gateway-meta-endpoint.test.ts | 138 ++-- test/gateway/did/did-gateway.test.ts | 129 ++-- test/gateway/did/get-did-status.test.ts | 84 ++- test/gateway/env-config-gateway.test.ts | 388 +++++------ test/gateway/jest.gateway.setup.ts | 10 +- test/gateway/json-stream.test.ts | 268 ++++---- ...lica-gateway-list-dataset-replicas.test.ts | 114 ++-- ...replica-gateway-list-file-replicas.test.ts | 107 ++- .../rse-gateway-get-rse-attributes.test.ts | 69 +- .../rse/rse-gateway-get-rse-protocols.test.ts | 274 ++++---- test/gateway/rse/rse-gateway-get-rse.test.ts | 42 +- .../gateway/rse/rse-gateway-list-rses.test.ts | 157 +++-- .../rule/rule-gateway-get-rule.test.ts | 162 ++--- ...eway-list-rule-replica-lock-states.test.ts | 86 +-- ...ule-gateway-list-rules-for-account.test.ts | 145 +++- .../list-subscription-rule-states.test.ts | 101 +-- .../subscription/subscription-gateway.test.ts | 177 +++-- test/sdk/fixtures/models.ts | 20 +- test/sdk/fixtures/pipeline-elements.ts | 80 +-- test/sdk/fixtures/presenter.ts | 72 +- test/sdk/jest.sdk.setup.ts | 10 +- .../multicall-usecase-sync.test.ts | 201 +++--- ...all-usecase-final-validation-error.test.ts | 110 ++-- .../multicall-usecase-pipeline-errors.test.ts | 133 ++-- .../multicall-usecase.test.ts | 189 +++--- test/sdk/stream-error-handling.test.ts | 145 ++-- test/sdk/streaming-transformers.test.ts | 256 ++++---- 79 files changed, 5198 insertions(+), 4299 deletions(-) diff --git a/src/lib/core/use-case/list-account-rse-quotas-usecase.ts b/src/lib/core/use-case/list-account-rse-quotas-usecase.ts index 509dd326c..6fab72777 100644 --- a/src/lib/core/use-case/list-account-rse-quotas-usecase.ts +++ b/src/lib/core/use-case/list-account-rse-quotas-usecase.ts @@ -94,9 +94,7 @@ export default class ListAccountRSEQuotasUseCase }); } - async generateSourceStream( - requestModel: AuthenticatedRequestModel>, - ): Promise<{ + async generateSourceStream(requestModel: AuthenticatedRequestModel>): Promise<{ status: 'success' | 'error'; stream?: Transform | Readable | PassThrough | null | undefined; error?: ListAccountRSEQuotasError | undefined; diff --git a/test/api/account/get-account-info.test.ts b/test/api/account/get-account-info.test.ts index 76da39d6e..8cafa8fa1 100644 --- a/test/api/account/get-account-info.test.ts +++ b/test/api/account/get-account-info.test.ts @@ -1,15 +1,15 @@ -import { AccountType } from "@/lib/core/entity/rucio"; -import { GetAccountInfoRequest } from "@/lib/core/usecase-models/get-account-info-usecase-models"; -import { GetAccountInfoControllerParameters } from "@/lib/infrastructure/controller/get-account-info-controller"; -import { AccountInfoViewModel } from "@/lib/infrastructure/data/view-model/account"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import CONTROLLERS from "@/lib/infrastructure/ioc/ioc-symbols-controllers"; -import { BaseController } from "@/lib/sdk/controller"; -import { NextApiResponse } from "next"; -import { createHttpMocks } from "test/fixtures/http-fixtures"; -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; +import { AccountType } from '@/lib/core/entity/rucio'; +import { GetAccountInfoRequest } from '@/lib/core/usecase-models/get-account-info-usecase-models'; +import { GetAccountInfoControllerParameters } from '@/lib/infrastructure/controller/get-account-info-controller'; +import { AccountInfoViewModel } from '@/lib/infrastructure/data/view-model/account'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers'; +import { BaseController } from '@/lib/sdk/controller'; +import { NextApiResponse } from 'next'; +import { createHttpMocks } from 'test/fixtures/http-fixtures'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; -describe("Get Account Info", () => { +describe('Get Account Info', () => { beforeEach(() => { fetchMock.doMock(); const accountInfoEndpoint: MockEndpoint = { @@ -22,40 +22,39 @@ describe("Get Account Info", () => { 'Content-Type': 'application/json', }, body: JSON.stringify({ - "status": "ACTIVE", - "deleted_at": null, - "updated_at": "2023-11-27T17:54:04", - "email": null, - "account_type": "SERVICE", - "suspended_at": null, - "account": "root", - "created_at": "2023-11-27T17:54:04" - }) - } - } + status: 'ACTIVE', + deleted_at: null, + updated_at: '2023-11-27T17:54:04', + email: null, + account_type: 'SERVICE', + suspended_at: null, + account: 'root', + created_at: '2023-11-27T17:54:04', + }), + }, + }; MockRucioServerFactory.createMockRucioServer(true, [accountInfoEndpoint]); }); afterEach(() => { fetchMock.dontMock(); }); - - it("should return a view model for a valid request to GetAccountInfo feature", async () => { - const { req, res, session } = await createHttpMocks('/api/did-meta', 'GET', {}) - - const controller = appContainer.get>(CONTROLLERS.GET_ACCOUNT_INFO) + + it('should return a view model for a valid request to GetAccountInfo feature', async () => { + const { req, res, session } = await createHttpMocks('/api/did-meta', 'GET', {}); + + const controller = appContainer.get>(CONTROLLERS.GET_ACCOUNT_INFO); const controllerParameters: GetAccountInfoControllerParameters = { response: res as unknown as NextApiResponse, rucioAuthToken: MockRucioServerFactory.VALID_RUCIO_TOKEN, - account: 'root' - } - - await controller.execute(controllerParameters) - expect(res._getStatusCode()).toBe(200) - const data: AccountInfoViewModel = await res._getJSONData() - expect(data.status).toBe('success') + account: 'root', + }; - expect(data.accountType).toBe(AccountType.SERVICE) + await controller.execute(controllerParameters); + expect(res._getStatusCode()).toBe(200); + const data: AccountInfoViewModel = await res._getJSONData(); + expect(data.status).toBe('success'); + expect(data.accountType).toBe(AccountType.SERVICE); }); -}); \ No newline at end of file +}); diff --git a/test/api/account/switch.test.ts b/test/api/account/switch.test.ts index 5b837a57d..2505c7cb9 100644 --- a/test/api/account/switch.test.ts +++ b/test/api/account/switch.test.ts @@ -1,10 +1,10 @@ -import { AuthType, Role, SessionUser } from "@/lib/core/entity/auth-models"; -import { addOrUpdateSessionUser } from "@/lib/infrastructure/auth/session-utils"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import CONTROLLERS from "@/lib/infrastructure/ioc/ioc-symbols-controllers"; -import { ISwitchAccountController } from "@/lib/infrastructure/controller/switch-account-controller"; -import { getIronSession } from "iron-session"; -import { createMocks } from "node-mocks-http"; +import { AuthType, Role, SessionUser } from '@/lib/core/entity/auth-models'; +import { addOrUpdateSessionUser } from '@/lib/infrastructure/auth/session-utils'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers'; +import { ISwitchAccountController } from '@/lib/infrastructure/controller/switch-account-controller'; +import { getIronSession } from 'iron-session'; +import { createMocks } from 'node-mocks-http'; describe('Switch Account API Test', () => { it('should switch to existing account in the session and redirect', async () => { @@ -17,9 +17,9 @@ describe('Switch Account API Test', () => { cookieOptions: { secure: false, }, - }) + }); - res.redirect = jest.fn() + res.redirect = jest.fn(); const mockUser: SessionUser = { rucioIdentity: 'ddmlab', @@ -33,7 +33,7 @@ describe('Switch Account API Test', () => { role: Role.ADMIN, countryRole: Role.ADMIN, isLoggedIn: true, - } + }; const mockUser2: SessionUser = { rucioIdentity: 'maany', @@ -47,27 +47,27 @@ describe('Switch Account API Test', () => { role: Role.ADMIN, countryRole: Role.ADMIN, isLoggedIn: true, - } + }; - await addOrUpdateSessionUser(session, mockUser2) - await addOrUpdateSessionUser(session, mockUser) + await addOrUpdateSessionUser(session, mockUser2); + await addOrUpdateSessionUser(session, mockUser); - expect(session.user?.rucioIdentity).toBe('ddmlab') + expect(session.user?.rucioIdentity).toBe('ddmlab'); - const switchAccountController: ISwitchAccountController = appContainer.get(CONTROLLERS.SWITCH_ACCOUNT) + const switchAccountController: ISwitchAccountController = appContainer.get(CONTROLLERS.SWITCH_ACCOUNT); await switchAccountController.handle( session, res as undefined as NextApiRequest, mockUser2.rucioIdentity, mockUser2.rucioAccount, - mockUser2.rucioAuthType, - '/rse' + mockUser2.rucioAuthType, + '/rse', ); - - expect(session.user?.rucioIdentity).toBe('maany') - expect(res.redirect).toBeCalledWith('/rse') + + expect(session.user?.rucioIdentity).toBe('maany'); + expect(res.redirect).toBeCalledWith('/rse'); }); - it('should not switch to non-existing account', async() => { + it('should not switch to non-existing account', async () => { const { req, res } = createMocks({ url: 'http://testhost:3000/api/site-header', }); @@ -77,9 +77,9 @@ describe('Switch Account API Test', () => { cookieOptions: { secure: false, }, - }) + }); - res.redirect = jest.fn() + res.redirect = jest.fn(); const mockUser: SessionUser = { rucioIdentity: 'ddmlab', @@ -93,7 +93,7 @@ describe('Switch Account API Test', () => { role: Role.ADMIN, countryRole: Role.ADMIN, isLoggedIn: true, - } + }; const mockUser2: SessionUser = { rucioIdentity: 'maany', @@ -107,23 +107,22 @@ describe('Switch Account API Test', () => { role: Role.ADMIN, countryRole: Role.ADMIN, isLoggedIn: true, - } + }; - await addOrUpdateSessionUser(session, mockUser) + await addOrUpdateSessionUser(session, mockUser); - const switchAccountController: ISwitchAccountController = appContainer.get(CONTROLLERS.SWITCH_ACCOUNT) + const switchAccountController: ISwitchAccountController = appContainer.get(CONTROLLERS.SWITCH_ACCOUNT); await switchAccountController.handle( session, res as undefined as NextApiRequest, mockUser2.rucioIdentity, mockUser2.rucioAccount, - mockUser2.rucioAuthType, - '/rse' + mockUser2.rucioAuthType, + '/rse', ); - expect(res._getStatusCode()).toBe(500) - const data = JSON.parse(res._getData()) - expect(data.error).toBe('Cannot switch to non-existing/logged-in account') - - }) -}); \ No newline at end of file + expect(res._getStatusCode()).toBe(500); + const data = JSON.parse(res._getData()); + expect(data.error).toBe('Cannot switch to non-existing/logged-in account'); + }); +}); diff --git a/test/api/auth/login-page-config.test.ts b/test/api/auth/login-page-config.test.ts index 980913d88..e232d62f0 100644 --- a/test/api/auth/login-page-config.test.ts +++ b/test/api/auth/login-page-config.test.ts @@ -1,21 +1,21 @@ -import { setEmptySession } from "@/lib/infrastructure/auth/session-utils"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import CONTROLLERS from "@/lib/infrastructure/ioc/ioc-symbols-controllers"; -import { LoginViewModel } from "@/lib/infrastructure/data/view-model/login"; -import { getIronSession } from "iron-session"; -import { createMocks } from "node-mocks-http"; -import { createOIDCProviders, deleteOIDCProviders } from "test/fixtures/oidc-provider-config"; -import { BaseController } from "@/lib/sdk/controller"; -import { LoginConfigControllerParams } from "@/lib/infrastructure/controller/login-config-controller"; +import { setEmptySession } from '@/lib/infrastructure/auth/session-utils'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers'; +import { LoginViewModel } from '@/lib/infrastructure/data/view-model/login'; +import { getIronSession } from 'iron-session'; +import { createMocks } from 'node-mocks-http'; +import { createOIDCProviders, deleteOIDCProviders } from 'test/fixtures/oidc-provider-config'; +import { BaseController } from '@/lib/sdk/controller'; +import { LoginConfigControllerParams } from '@/lib/infrastructure/controller/login-config-controller'; describe('Login Page Config API Test', () => { beforeEach(() => { - createOIDCProviders() - }) + createOIDCProviders(); + }); afterEach(() => { fetchMock.resetMocks(); - deleteOIDCProviders() - }) + deleteOIDCProviders(); + }); it('should present successful LoginViewModel for singleVO', async () => { const { req, res } = createMocks({ @@ -27,10 +27,10 @@ describe('Login Page Config API Test', () => { cookieOptions: { secure: false, }, - }) - await setEmptySession(session, true) + }); + await setEmptySession(session, true); - const loginConfigController = appContainer.get>(CONTROLLERS.LOGIN_CONFIG) + const loginConfigController = appContainer.get>(CONTROLLERS.LOGIN_CONFIG); await loginConfigController.execute({ session: session, response: res as any, @@ -38,7 +38,7 @@ describe('Login Page Config API Test', () => { expect(res._getStatusCode()).toBe(200); const viewModel: LoginViewModel = JSON.parse(res._getData()); - + expect(viewModel).toHaveProperty('status'); expect(viewModel.status).toBe('success'); expect(viewModel).toHaveProperty('isLoggedIn'); @@ -51,7 +51,7 @@ describe('Login Page Config API Test', () => { expect(viewModel.oidcProviders).toHaveLength(2); expect(viewModel.oidcProviders[0]).toHaveProperty('name'); expect(viewModel.oidcProviders[0].name).toBe('cern'); - + expect(viewModel).toHaveProperty('rucioAuthHost'); expect(viewModel.rucioAuthHost).toBe('https://rucio-auth-host.com'); @@ -61,7 +61,7 @@ describe('Login Page Config API Test', () => { expect(viewModel.voList).toHaveLength(1); expect(viewModel.voList[0]).toHaveProperty('name'); expect(viewModel.voList[0].name).toBe('default'); - }) + }); it('should present successful LoginViewModel for multiVO', async () => { const { req, res } = createMocks({ @@ -73,18 +73,17 @@ describe('Login Page Config API Test', () => { cookieOptions: { secure: false, }, - }) - await setEmptySession(session, true) - - process.env['MULTIVO_ENABLED'] = 'true' - process.env['VO_LIST'] = 'vo1,vo2' - process.env['VO_VO1_NAME'] = 'vo1' - process.env['VO_VO1_OIDC_ENABLED'] = 'true' - process.env['VO_VO1_OIDC_PROVIDERS'] = 'cern' - process.env['VO_VO2_NAME'] = 'vo2' + }); + await setEmptySession(session, true); + process.env['MULTIVO_ENABLED'] = 'true'; + process.env['VO_LIST'] = 'vo1,vo2'; + process.env['VO_VO1_NAME'] = 'vo1'; + process.env['VO_VO1_OIDC_ENABLED'] = 'true'; + process.env['VO_VO1_OIDC_PROVIDERS'] = 'cern'; + process.env['VO_VO2_NAME'] = 'vo2'; - const loginConfigController = appContainer.get>(CONTROLLERS.LOGIN_CONFIG) + const loginConfigController = appContainer.get>(CONTROLLERS.LOGIN_CONFIG); await loginConfigController.execute({ session: session, response: res as any, @@ -116,27 +115,26 @@ describe('Login Page Config API Test', () => { expect(viewModel.voList[0].oidcProviders[0]).toHaveProperty('name'); expect(viewModel.voList[0].oidcProviders[0].name).toBe('cern'); - - }) + }); it('should present LoginConfigError for invalid or missing config', async () => { const { req, res } = createMocks({ method: 'POST', }); - + const session = await getIronSession(req, res, { password: 'passwordpasswordpasswordpasswordpassword', cookieName: 'test-request-session', cookieOptions: { secure: false, }, - }) - - await setEmptySession(session, true) - - delete process.env['OIDC_PROVIDERS'] - - const loginConfigController = appContainer.get>(CONTROLLERS.LOGIN_CONFIG) + }); + + await setEmptySession(session, true); + + delete process.env['OIDC_PROVIDERS']; + + const loginConfigController = appContainer.get>(CONTROLLERS.LOGIN_CONFIG); await loginConfigController.execute({ session: session, response: res as any, @@ -150,5 +148,5 @@ describe('Login Page Config API Test', () => { expect(viewModel).toHaveProperty('message'); expect(viewModel.message).toContain('OIDC_PROVIDERS'); - }) -}) \ No newline at end of file + }); +}); diff --git a/test/api/auth/session.test.ts b/test/api/auth/session.test.ts index 398fa87f7..a4f811735 100644 --- a/test/api/auth/session.test.ts +++ b/test/api/auth/session.test.ts @@ -1,7 +1,7 @@ -import { AuthType, Role, SessionUser } from "@/lib/core/entity/auth-models"; -import { addOrUpdateSessionUser, removeSessionUser, setActiveSessionUser, setEmptySession } from "@/lib/infrastructure/auth/session-utils"; -import { getIronSession, IronSession } from "iron-session"; -import { createMocks } from "node-mocks-http"; +import { AuthType, Role, SessionUser } from '@/lib/core/entity/auth-models'; +import { addOrUpdateSessionUser, removeSessionUser, setActiveSessionUser, setEmptySession } from '@/lib/infrastructure/auth/session-utils'; +import { getIronSession, IronSession } from 'iron-session'; +import { createMocks } from 'node-mocks-http'; describe('IronSession tests', () => { it('should set and get a value in the session', async () => { @@ -9,8 +9,8 @@ describe('IronSession tests', () => { method: 'POST', body: { username: 'ddmlab', - password: 'secret' - } + password: 'secret', + }, }); const session: IronSession = await getIronSession(req, res, { password: 'passwordpasswordpasswordpasswordpassword', @@ -18,10 +18,10 @@ describe('IronSession tests', () => { cookieOptions: { secure: false, }, - }) + }); expect(session.user).toBeUndefined(); - - await setEmptySession(session, true) + + await setEmptySession(session, true); expect(session.user).toBeDefined(); expect(session.allUsers).toHaveLength(1); @@ -34,8 +34,8 @@ describe('IronSession tests', () => { role: Role.ADMIN, rucioOIDCProvider: 'cern', rucioVO: 'def', - isLoggedIn: true - } + isLoggedIn: true, + }; await session.save(); expect(session.user).toHaveProperty('rucioIdentity'); expect(session.user?.rucioIdentity).toBe('ddmlab'); @@ -45,7 +45,6 @@ describe('IronSession tests', () => { expect(session.user?.rucioAccount).toBe('root'); expect(session.user).toHaveProperty('isLoggedIn'); expect(session.user?.isLoggedIn).toBe(true); - }); it('should add a new, update and delete user to/from the session', async () => { @@ -53,8 +52,8 @@ describe('IronSession tests', () => { method: 'POST', body: { username: 'ddmlab', - password: 'secret' - } + password: 'secret', + }, }); const session: IronSession = await getIronSession(req, res, { password: 'passwordpasswordpasswordpasswordpassword', @@ -62,10 +61,10 @@ describe('IronSession tests', () => { cookieOptions: { secure: false, }, - }) + }); session.allUsers = []; - + const sessionUserPassDDMLab: SessionUser = { rucioAuthToken: 'rucio-ddmlab-adadadad', rucioAuthTokenExpires: '2021-09-01T12:00:00Z', @@ -75,8 +74,8 @@ describe('IronSession tests', () => { role: Role.ADMIN, rucioVO: 'def', rucioOIDCProvider: null, - isLoggedIn: true - } + isLoggedIn: true, + }; const sessionUserX509DDMLab: SessionUser = { rucioAuthToken: 'rucio-ddmlab-adasfgdbg', @@ -87,8 +86,8 @@ describe('IronSession tests', () => { role: Role.ADMIN, rucioVO: 'def', rucioOIDCProvider: null, - isLoggedIn: true - } + isLoggedIn: true, + }; await addOrUpdateSessionUser(session, sessionUserPassDDMLab); expect(session.allUsers).toHaveLength(1); @@ -110,8 +109,8 @@ describe('IronSession tests', () => { method: 'POST', body: { username: 'ddmlab', - password: 'secret' - } + password: 'secret', + }, }); const session: IronSession = await getIronSession(req, res, { password: 'passwordpasswordpasswordpasswordpassword', @@ -119,7 +118,7 @@ describe('IronSession tests', () => { cookieOptions: { secure: false, }, - }) + }); const sessionUserPassDDMLab: SessionUser = { rucioAuthToken: 'rucio-ddmlab-adadadad', rucioAuthTokenExpires: '2021-09-01T12:00:00Z', @@ -129,8 +128,8 @@ describe('IronSession tests', () => { role: Role.USER, rucioOIDCProvider: null, rucioVO: 'def', - isLoggedIn: true - } + isLoggedIn: true, + }; const autreUser: SessionUser = { rucioAuthToken: 'rucio-autre-adagfdsfg', @@ -141,8 +140,8 @@ describe('IronSession tests', () => { role: Role.USER, rucioOIDCProvider: null, rucioVO: 'def', - isLoggedIn: true - } + isLoggedIn: true, + }; await setActiveSessionUser(session, sessionUserPassDDMLab); expect(session.user?.rucioAuthToken).toBe('rucio-ddmlab-adadadad'); @@ -158,6 +157,5 @@ describe('IronSession tests', () => { await removeSessionUser(session, autreUser); expect(session.user).toBeUndefined(); expect(session.allUsers).toHaveLength(0); - }); -}) \ No newline at end of file +}); diff --git a/test/api/auth/userpass.test.ts b/test/api/auth/userpass.test.ts index ae910a644..8644a08be 100644 --- a/test/api/auth/userpass.test.ts +++ b/test/api/auth/userpass.test.ts @@ -8,11 +8,10 @@ import { getIronSession } from 'iron-session'; import { setEmptySession } from '@/lib/infrastructure/auth/session-utils'; import { Role } from '@/lib/core/entity/auth-models'; - describe('UserPassLogin API Test', () => { beforeEach(() => { fetchMock.doMock(); - fetchMock.mockIf(/^https?:\/\/rucio-.*.com.*$/, (req) => { + fetchMock.mockIf(/^https?:\/\/rucio-.*.com.*$/, req => { if (req.url.endsWith('/auth/userpass')) { return Promise.resolve({ status: 200, @@ -20,18 +19,17 @@ describe('UserPassLogin API Test', () => { 'Content-Type': 'application/json', 'X-Rucio-Auth-Token': 'rucio-ddmlab-askdjljioj', 'X-Rucio-Auth-Account': 'root', - 'X-Rucio-Auth-Token-Expires': '2021-09-01T00:00:00.000Z' + 'X-Rucio-Auth-Token-Expires': '2021-09-01T00:00:00.000Z', }, - body: JSON.stringify({ - }) - }) + body: JSON.stringify({}), + }); } - if(req.url.endsWith('/accounts/root/attr')){ - const rucioToken = req.headers.get('X-Rucio-Auth-Token') - if(rucioToken !== 'rucio-ddmlab-askdjljioj') { + if (req.url.endsWith('/accounts/root/attr')) { + const rucioToken = req.headers.get('X-Rucio-Auth-Token'); + if (rucioToken !== 'rucio-ddmlab-askdjljioj') { return Promise.resolve({ status: 401, - }) + }); } return Promise.resolve({ status: 200, @@ -40,26 +38,26 @@ describe('UserPassLogin API Test', () => { }, body: JSON.stringify([ { - "key": "admin", - "value": "True" + key: 'admin', + value: 'True', }, { - "key": "country-tw", - "value": "user" - } - ]) - }) + key: 'country-tw', + value: 'user', + }, + ]), + }); } - }) - }) - + }); + }); + it('should present successful LoginViewModel', async () => { const { req, res } = createMocks({ method: 'POST', body: { username: 'ddmlab', password: 'secret', - } + }, }); const session = await getIronSession(req, res, { password: 'passwordpasswordpasswordpasswordpassword', @@ -67,12 +65,20 @@ describe('UserPassLogin API Test', () => { cookieOptions: { secure: false, }, - }) - - await setEmptySession(session, true) + }); - const userpassLoginController = appContainer.get(CONTROLLERS.USERPASS_LOGIN) - await userpassLoginController.handle(req.body.username, req.body.password, 'root', 'def', session, res as undefined as NextApiResponse, '/dashboard'); + await setEmptySession(session, true); + + const userpassLoginController = appContainer.get(CONTROLLERS.USERPASS_LOGIN); + await userpassLoginController.handle( + req.body.username, + req.body.password, + 'root', + 'def', + session, + res as undefined as NextApiResponse, + '/dashboard', + ); expect(res._getStatusCode()).toBe(200); const viewModel: AuthViewModel = JSON.parse(res._getData()); expect(viewModel).toHaveProperty('rucioIdentity'); @@ -83,12 +89,12 @@ describe('UserPassLogin API Test', () => { expect(viewModel.rucioAccount).toBe('root'); expect(viewModel).toHaveProperty('rucioAuthTokenExpires'); expect(viewModel.rucioAuthTokenExpires).toBe('2021-09-01T00:00:00.000Z'); - expect(viewModel).toHaveProperty('role') - expect(viewModel.role).toBe(Role.ADMIN) - expect(viewModel).toHaveProperty('country') - expect(viewModel.country).toBe('tw') - expect(viewModel).toHaveProperty('countryRole') - expect(viewModel.countryRole).toBe('user') + expect(viewModel).toHaveProperty('role'); + expect(viewModel.role).toBe(Role.ADMIN); + expect(viewModel).toHaveProperty('country'); + expect(viewModel.country).toBe('tw'); + expect(viewModel).toHaveProperty('countryRole'); + expect(viewModel.countryRole).toBe('user'); expect(session.user).toHaveProperty('rucioIdentity'); expect(session.user?.rucioIdentity).toBe('ddmlab'); @@ -100,12 +106,11 @@ describe('UserPassLogin API Test', () => { expect(session.user?.isLoggedIn).toBe(true); expect(session.user).toHaveProperty('rucioAuthTokenExpires'); expect(session.user?.rucioAuthTokenExpires).toBe('2021-09-01T00:00:00.000Z'); - expect(session.user).toHaveProperty('role') - expect(session.user?.role).toBe(Role.ADMIN) - expect(session.user).toHaveProperty('country') - expect(session.user?.country).toBe('tw') - expect(session.user).toHaveProperty('countryRole') - expect(session.user?.countryRole).toBe('user') + expect(session.user).toHaveProperty('role'); + expect(session.user?.role).toBe(Role.ADMIN); + expect(session.user).toHaveProperty('country'); + expect(session.user?.country).toBe('tw'); + expect(session.user).toHaveProperty('countryRole'); + expect(session.user?.countryRole).toBe('user'); }); - -}); \ No newline at end of file +}); diff --git a/test/api/auth/x509-session.test.ts b/test/api/auth/x509-session.test.ts index 386049ce8..d236ae744 100644 --- a/test/api/auth/x509-session.test.ts +++ b/test/api/auth/x509-session.test.ts @@ -1,24 +1,24 @@ -import { setEmptySession } from "@/lib/infrastructure/auth/session-utils"; -import { getIronSession } from "iron-session"; -import { createMocks } from "node-mocks-http"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import { ISetX509LoginSessionController } from "@/lib/infrastructure/controller/set-x509-login-session-controller"; -import CONTROLLERS from "@/lib/infrastructure/ioc/ioc-symbols-controllers"; -import { AuthViewModel } from "@/lib/infrastructure/data/auth/auth"; -import { Role } from "@/lib/core/entity/auth-models"; +import { setEmptySession } from '@/lib/infrastructure/auth/session-utils'; +import { getIronSession } from 'iron-session'; +import { createMocks } from 'node-mocks-http'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import { ISetX509LoginSessionController } from '@/lib/infrastructure/controller/set-x509-login-session-controller'; +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers'; +import { AuthViewModel } from '@/lib/infrastructure/data/auth/auth'; +import { Role } from '@/lib/core/entity/auth-models'; describe('X509Login API Test', () => { beforeEach(() => { fetchMock.resetMocks(); fetchMock.doMock(); - fetchMock.mockIf(/^https?:\/\/rucio-host.com.*$/, (req) => { - if(req.url.endsWith('/accounts/root/attr')){ - const rucioToken = req.headers.get('X-Rucio-Auth-Token') - if(rucioToken !== 'rucio-/C=GB/O=Isode Limited/CN=Steve Kille-askdjljioj') { + fetchMock.mockIf(/^https?:\/\/rucio-host.com.*$/, req => { + if (req.url.endsWith('/accounts/root/attr')) { + const rucioToken = req.headers.get('X-Rucio-Auth-Token'); + if (rucioToken !== 'rucio-/C=GB/O=Isode Limited/CN=Steve Kille-askdjljioj') { return Promise.resolve({ status: 401, - }) + }); } return Promise.resolve({ status: 200, @@ -27,18 +27,18 @@ describe('X509Login API Test', () => { }, body: JSON.stringify([ { - "key": "admin", - "value": "True" + key: 'admin', + value: 'True', }, { - "key": "country-tw", - "value": "user" - } - ]) - }) - } - }) - }) + key: 'country-tw', + value: 'user', + }, + ]), + }); + } + }); + }); it('should set session user upon successful login via x509 workflow', async () => { const { req, res } = createMocks({ method: 'POST', @@ -47,7 +47,7 @@ describe('X509Login API Test', () => { rucioAuthToken: 'rucio-/C=GB/O=Isode Limited/CN=Steve Kille-askdjljioj', rucioTokenExpiry: '2021-09-01T00:00:00.000Z', shortVOName: 'def', - } + }, }); const session = await getIronSession(req, res, { password: 'passwordpasswordpasswordpasswordpassword', @@ -55,19 +55,19 @@ describe('X509Login API Test', () => { cookieOptions: { secure: false, }, - }) - req.session = session - const requestBody = req.body - await setEmptySession(session, true) - const setX509LoginSessionController = appContainer.get(CONTROLLERS.SET_X509_LOGIN_SESSION) + }); + req.session = session; + const requestBody = req.body; + await setEmptySession(session, true); + const setX509LoginSessionController = appContainer.get(CONTROLLERS.SET_X509_LOGIN_SESSION); await setX509LoginSessionController.handle( - session, - res, - requestBody.rucioAuthToken, - requestBody.rucioAccount, - requestBody.shortVOName, - requestBody.rucioTokenExpiry - ) + session, + res, + requestBody.rucioAuthToken, + requestBody.rucioAccount, + requestBody.shortVOName, + requestBody.rucioTokenExpiry, + ); expect(res._getStatusCode()).toBe(200); expect(session.user).toHaveProperty('isLoggedIn'); @@ -76,17 +76,17 @@ describe('X509Login API Test', () => { expect(session.user?.rucioAuthToken).toBe('rucio-/C=GB/O=Isode Limited/CN=Steve Kille-askdjljioj'); expect(session.user).toHaveProperty('rucioAccount'); expect(session.user?.rucioAccount).toBe('root'); - expect(session.user).toHaveProperty('rucioIdentity') + expect(session.user).toHaveProperty('rucioIdentity'); expect(session.user?.rucioIdentity).toBe('/C=GB/O=Isode Limited/CN=Steve Kille'); - expect(session.user).toHaveProperty('rucioAuthType') + expect(session.user).toHaveProperty('rucioAuthType'); expect(session.user?.rucioAuthType).toBe('x509'); - expect(session.user).toHaveProperty('rucioAuthTokenExpires') + expect(session.user).toHaveProperty('rucioAuthTokenExpires'); expect(session.user?.rucioAuthTokenExpires).toBe('2021-09-01T00:00:00.000Z'); - expect(session.user).toHaveProperty('role') + expect(session.user).toHaveProperty('role'); expect(session.user?.role).toBe(Role.ADMIN); - expect(session.user).toHaveProperty('country') + expect(session.user).toHaveProperty('country'); expect(session.user?.country).toBe('tw'); - expect(session.user).toHaveProperty('countryRole') + expect(session.user).toHaveProperty('countryRole'); expect(session.user?.countryRole).toBe('user'); const response: AuthViewModel = JSON.parse(res._getData()); @@ -108,8 +108,7 @@ describe('X509Login API Test', () => { expect(response.country).toBe('tw'); expect(response).toHaveProperty('countryRole'); expect(response.countryRole).toBe('user'); - - }) + }); it('should return 500 if session is not initialized due to invalid VO', async () => { const { req, res } = createMocks({ @@ -119,7 +118,7 @@ describe('X509Login API Test', () => { rucioAuthToken: 'rucio-ddmlab-askdjljioj', rucioTokenExpiry: '2021-09-01T00:00:00.000Z', shortVOName: 'ERROR_VO_WILL_NOT_BE_FOUND', - } + }, }); const session = await getIronSession(req, res, { password: 'passwordpasswordpasswordpasswordpassword', @@ -127,19 +126,19 @@ describe('X509Login API Test', () => { cookieOptions: { secure: false, }, - }) - req.session = session - const requestBody = req.body - await setEmptySession(session, true) - const setX509LoginSessionController = appContainer.get(CONTROLLERS.SET_X509_LOGIN_SESSION) + }); + req.session = session; + const requestBody = req.body; + await setEmptySession(session, true); + const setX509LoginSessionController = appContainer.get(CONTROLLERS.SET_X509_LOGIN_SESSION); await setX509LoginSessionController.handle( - session, - res, - requestBody.rucioAuthToken, - requestBody.rucioAccount, - requestBody.shortVOName, - requestBody.rucioTokenExpiry - ) + session, + res, + requestBody.rucioAuthToken, + requestBody.rucioAccount, + requestBody.shortVOName, + requestBody.rucioTokenExpiry, + ); expect(res._getStatusCode()).toBe(500); expect(session.user).toHaveProperty('isLoggedIn'); @@ -154,6 +153,5 @@ describe('X509Login API Test', () => { expect(response.status).toBe('error'); expect(response).toHaveProperty('message'); expect(response.message).toContain('ERROR_VO_WILL_NOT_BE_FOUND'); - - }) -}) \ No newline at end of file + }); +}); diff --git a/test/api/did/did-keyvaluepairs.test.ts b/test/api/did/did-keyvaluepairs.test.ts index fd705ad37..5223fecb9 100644 --- a/test/api/did/did-keyvaluepairs.test.ts +++ b/test/api/did/did-keyvaluepairs.test.ts @@ -1,54 +1,54 @@ -import { DIDKeyValuePairsDataRequest } from "@/lib/core/usecase-models/did-keyvaluepairs-usecase-models" -import { DIDKeyValuePairsDataControllerParameters } from "@/lib/infrastructure/controller/did-keyvaluepairs-controller" -import appContainer from "@/lib/infrastructure/ioc/container-config" -import CONTROLLERS from "@/lib/infrastructure/ioc/ioc-symbols-controllers" -import { BaseController } from "@/lib/sdk/controller" -import { createHttpMocks } from "test/fixtures/http-fixtures" -import { NextApiResponse } from "next" -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server" +import { DIDKeyValuePairsDataRequest } from '@/lib/core/usecase-models/did-keyvaluepairs-usecase-models'; +import { DIDKeyValuePairsDataControllerParameters } from '@/lib/infrastructure/controller/did-keyvaluepairs-controller'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers'; +import { BaseController } from '@/lib/sdk/controller'; +import { createHttpMocks } from 'test/fixtures/http-fixtures'; +import { NextApiResponse } from 'next'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; -describe("DID KeyValuePairs API Tests", () => { +describe('DID KeyValuePairs API Tests', () => { beforeEach(() => { - fetchMock.doMock() + fetchMock.doMock(); const didKeyValuePairsMockEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/dids/test/dataset1/meta`, - method: "GET", - includes: "test/dataset1/meta", + method: 'GET', + includes: 'test/dataset1/meta', response: { status: 200, headers: { - "Content-Type": "application/json", + 'Content-Type': 'application/json', }, body: JSON.stringify({ - "scope": "test", - "name": "dataset1", - "bro": "not here", - "numberval": 123, - }) - } - } + scope: 'test', + name: 'dataset1', + bro: 'not here', + numberval: 123, + }), + }, + }; MockRucioServerFactory.createMockRucioServer(true, [didKeyValuePairsMockEndpoint]); - }) + }); afterEach(() => { - fetchMock.dontMock() - }) - it("should return a DIDKeyValuePairsResponse", async () => { - const { req, res, session } = await createHttpMocks('/api/did-keyvaluepairs', 'GET', {}) - const didKVController = appContainer.get< - BaseController - >(CONTROLLERS.DID_KEYVALUEPAIRS) + fetchMock.dontMock(); + }); + it('should return a DIDKeyValuePairsResponse', async () => { + const { req, res, session } = await createHttpMocks('/api/did-keyvaluepairs', 'GET', {}); + const didKVController = appContainer.get>( + CONTROLLERS.DID_KEYVALUEPAIRS, + ); const didKVControllerParams: DIDKeyValuePairsDataControllerParameters = { - name: "test/dataset1", - scope: "test", + name: 'test/dataset1', + scope: 'test', rucioAuthToken: MockRucioServerFactory.VALID_RUCIO_TOKEN, - response: res as unknown as NextApiResponse - } - await didKVController.execute(didKVControllerParams) - expect(res._getStatusCode()).toBe(200) - const data = JSON.parse(res._getData()) - expect(data.status).toBe('success') - expect(data.data).toHaveLength(4) - expect(data.data).toContainEqual({ key: 'scope', value: 'test' }) - expect(data.data).toContainEqual({ key: 'numberval', value: 123 }) - }) -}) \ No newline at end of file + response: res as unknown as NextApiResponse, + }; + await didKVController.execute(didKVControllerParams); + expect(res._getStatusCode()).toBe(200); + const data = JSON.parse(res._getData()); + expect(data.status).toBe('success'); + expect(data.data).toHaveLength(4); + expect(data.data).toContainEqual({ key: 'scope', value: 'test' }); + expect(data.data).toContainEqual({ key: 'numberval', value: 123 }); + }); +}); diff --git a/test/api/did/did-meta.test.ts b/test/api/did/did-meta.test.ts index 3ecc8d820..7573da3f3 100644 --- a/test/api/did/did-meta.test.ts +++ b/test/api/did/did-meta.test.ts @@ -1,94 +1,94 @@ -import { DIDMetaRequest } from "@/lib/core/usecase-models/did-meta-usecase-models"; -import { DIDMetaControllerParameters } from "@/lib/infrastructure/controller/did-meta-controller"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import CONTROLLERS from "@/lib/infrastructure/ioc/ioc-symbols-controllers"; -import { BaseController } from "@/lib/sdk/controller"; -import { NextApiResponse } from "next"; -import { createHttpMocks } from "test/fixtures/http-fixtures"; -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; +import { DIDMetaRequest } from '@/lib/core/usecase-models/did-meta-usecase-models'; +import { DIDMetaControllerParameters } from '@/lib/infrastructure/controller/did-meta-controller'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers'; +import { BaseController } from '@/lib/sdk/controller'; +import { NextApiResponse } from 'next'; +import { createHttpMocks } from 'test/fixtures/http-fixtures'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; -describe("DID Meta API Tests", () => { +describe('DID Meta API Tests', () => { beforeEach(() => { - fetchMock.doMock() + fetchMock.doMock(); const didMetaMMockEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/dids/test/dataset1/meta`, - method: "GET", - includes: "test/dataset1/meta", + method: 'GET', + includes: 'test/dataset1/meta', response: { status: 200, headers: { - "Content-Type": "application/json", + 'Content-Type': 'application/json', }, body: JSON.stringify({ - "scope": "test", - "name": "dataset1", - "account": "root", - "did_type": "DATASET", - "is_open": true, - "monotonic": false, - "hidden": false, - "obsolete": false, - "complete": null, - "is_new": true, - "availability": "AVAILABLE", - "suppressed": false, - "bytes": null, - "length": null, - "md5": null, - "adler32": null, - "expired_at": null, - "purge_replicas": true, - "deleted_at": null, - "events": null, - "guid": null, - "project": null, - "datatype": null, - "run_number": null, - "stream_name": null, - "prod_step": null, - "version": null, - "campaign": null, - "task_id": null, - "panda_id": null, - "lumiblocknr": null, - "provenance": null, - "phys_group": null, - "transient": false, - "accessed_at": null, - "closed_at": null, - "eol_at": null, - "is_archive": null, - "constituent": null, - "access_cnt": null, - "created_at": "Mon, 10 Jul 2023 13:23:56 UTC", - "updated_at": "Mon, 10 Jul 2023 13:23:56 UTC" - }) - } - } + scope: 'test', + name: 'dataset1', + account: 'root', + did_type: 'DATASET', + is_open: true, + monotonic: false, + hidden: false, + obsolete: false, + complete: null, + is_new: true, + availability: 'AVAILABLE', + suppressed: false, + bytes: null, + length: null, + md5: null, + adler32: null, + expired_at: null, + purge_replicas: true, + deleted_at: null, + events: null, + guid: null, + project: null, + datatype: null, + run_number: null, + stream_name: null, + prod_step: null, + version: null, + campaign: null, + task_id: null, + panda_id: null, + lumiblocknr: null, + provenance: null, + phys_group: null, + transient: false, + accessed_at: null, + closed_at: null, + eol_at: null, + is_archive: null, + constituent: null, + access_cnt: null, + created_at: 'Mon, 10 Jul 2023 13:23:56 UTC', + updated_at: 'Mon, 10 Jul 2023 13:23:56 UTC', + }), + }, + }; MockRucioServerFactory.createMockRucioServer(true, [didMetaMMockEndpoint]); - }) + }); afterEach(() => { - fetchMock.dontMock() - }) - it("should return a DIDMetaViewModel", async () => { - const { req, res, session } = await createHttpMocks('/api/did-meta', 'GET', {}) + fetchMock.dontMock(); + }); + it('should return a DIDMetaViewModel', async () => { + const { req, res, session } = await createHttpMocks('/api/did-meta', 'GET', {}); - const didMetaController = appContainer.get>(CONTROLLERS.DID_META) + const didMetaController = appContainer.get>(CONTROLLERS.DID_META); const didMetaControllerParams: DIDMetaControllerParameters = { name: 'dataset1', scope: 'test', rucioAuthToken: MockRucioServerFactory.VALID_RUCIO_TOKEN, - response: res as unknown as NextApiResponse - } - await didMetaController.execute(didMetaControllerParams) - expect(res._getStatusCode()).toBe(200) - const data = JSON.parse(res._getData()) - expect(data.status).toBe('success') - expect(data.name).toBe('dataset1') - expect(data.scope).toBe('test') - expect(data.account).toBe('root') - expect(data.did_type).toBe('Dataset') - expect(data.is_open).toBe(true) - expect(data.created_at).toBe('Mon, 10 Jul 2023 13:23:56 UTC') - }) -}) \ No newline at end of file + response: res as unknown as NextApiResponse, + }; + await didMetaController.execute(didMetaControllerParams); + expect(res._getStatusCode()).toBe(200); + const data = JSON.parse(res._getData()); + expect(data.status).toBe('success'); + expect(data.name).toBe('dataset1'); + expect(data.scope).toBe('test'); + expect(data.account).toBe('root'); + expect(data.did_type).toBe('Dataset'); + expect(data.is_open).toBe(true); + expect(data.created_at).toBe('Mon, 10 Jul 2023 13:23:56 UTC'); + }); +}); diff --git a/test/api/did/list-did-contents.test.ts b/test/api/did/list-did-contents.test.ts index 2578235b8..1396ce1dc 100644 --- a/test/api/did/list-did-contents.test.ts +++ b/test/api/did/list-did-contents.test.ts @@ -1,15 +1,15 @@ -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import CONTROLLERS from "@/lib/infrastructure/ioc/ioc-symbols-controllers"; -import { BaseController } from "@/lib/sdk/controller"; -import { NextApiResponse } from "next"; -import { MockHttpStreamableResponseFactory } from "test/fixtures/http-fixtures"; -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; -import { Readable } from "stream"; -import { DIDType } from "@/lib/core/entity/rucio"; -import { ListDIDContentsControllerParameters } from "@/lib/infrastructure/controller/list-did-contents-controller"; -import { ListDIDContentsRequest } from "@/lib/core/usecase-models/list-did-contents-usecase-models"; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers'; +import { BaseController } from '@/lib/sdk/controller'; +import { NextApiResponse } from 'next'; +import { MockHttpStreamableResponseFactory } from 'test/fixtures/http-fixtures'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; +import { Readable } from 'stream'; +import { DIDType } from '@/lib/core/entity/rucio'; +import { ListDIDContentsControllerParameters } from '@/lib/infrastructure/controller/list-did-contents-controller'; +import { ListDIDContentsRequest } from '@/lib/core/usecase-models/list-did-contents-usecase-models'; -describe("List DID Contents Feature tests", () => { +describe('List DID Contents Feature tests', () => { beforeEach(() => { fetchMock.doMock(); const didListContentsMockEndpoint: MockEndpoint = { @@ -23,12 +23,26 @@ describe("List DID Contents Feature tests", () => { }, body: Readable.from( [ - JSON.stringify({"scope": "test", "name": "file1", "type": "FILE", "bytes": 10485760, "adler32": "517daa38", "md5": "e4319066a5d3771954652a6905cebe82"}), - JSON.stringify({"scope": "test", "name": "file2", "type": "FILE", "bytes": 10485760, "adler32": "fc6ff847", "md5": "bcc3619205bf64d3cbe984b27c042a01"}), - ].join('\n') - ) - } - } + JSON.stringify({ + scope: 'test', + name: 'file1', + type: 'FILE', + bytes: 10485760, + adler32: '517daa38', + md5: 'e4319066a5d3771954652a6905cebe82', + }), + JSON.stringify({ + scope: 'test', + name: 'file2', + type: 'FILE', + bytes: 10485760, + adler32: 'fc6ff847', + md5: 'bcc3619205bf64d3cbe984b27c042a01', + }), + ].join('\n'), + ), + }, + }; MockRucioServerFactory.createMockRucioServer(true, [didListContentsMockEndpoint]); }); @@ -36,51 +50,52 @@ describe("List DID Contents Feature tests", () => { afterEach(() => { fetchMock.dontMock(); }); - it("should list DID contents", async () => { + it('should list DID contents', async () => { const res = MockHttpStreamableResponseFactory.getMockResponse(); - const listDIDContentsController = appContainer.get>(CONTROLLERS.LIST_DID_CONTENTS); + const listDIDContentsController = appContainer.get>( + CONTROLLERS.LIST_DID_CONTENTS, + ); const listDIDContentsControllerParams: ListDIDContentsControllerParameters = { response: res as unknown as NextApiResponse, rucioAuthToken: MockRucioServerFactory.VALID_RUCIO_TOKEN, name: 'dataset1', - scope: 'test' - } + scope: 'test', + }; await listDIDContentsController.execute(listDIDContentsControllerParams); - const receivedData: any[] = [] + const receivedData: any[] = []; const onData = (data: any) => { - receivedData.push(JSON.parse(data)) - } + receivedData.push(JSON.parse(data)); + }; const done = new Promise((resolve, reject) => { - res.on('data', onData) + res.on('data', onData); res.on('end', () => { - res.off('data', onData) - resolve() - }) + res.off('data', onData); + resolve(); + }); res.on('error', err => { - res.off('data', onData) - reject(err) - }) - }) + res.off('data', onData); + reject(err); + }); + }); - await done - console.log(receivedData) - expect(receivedData.length).toBe(2) + await done; + console.log(receivedData); + expect(receivedData.length).toBe(2); expect(receivedData[0]).toEqual({ - "status": "success", - "scope": "test", - "name": "file1", - "did_type": DIDType.FILE - }) + status: 'success', + scope: 'test', + name: 'file1', + did_type: DIDType.FILE, + }); expect(receivedData[1]).toEqual({ - "status": "success", - "scope": "test", - "name": "file2", - "did_type": DIDType.FILE - }) - + status: 'success', + scope: 'test', + name: 'file2', + did_type: DIDType.FILE, + }); }); -}); \ No newline at end of file +}); diff --git a/test/api/did/list-did-parents.test.ts b/test/api/did/list-did-parents.test.ts index 7adc25fa2..4c50be91f 100644 --- a/test/api/did/list-did-parents.test.ts +++ b/test/api/did/list-did-parents.test.ts @@ -1,38 +1,40 @@ -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import CONTROLLERS from "@/lib/infrastructure/ioc/ioc-symbols-controllers"; -import { BaseController } from "@/lib/sdk/controller"; -import { NextApiResponse } from "next"; -import { MockHttpStreamableResponseFactory } from "test/fixtures/http-fixtures"; -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; -import { Readable } from "stream"; -import { ListDIDParentsControllerParameters } from "@/lib/infrastructure/controller/list-did-parents-controller"; -import { ListDIDParentsRequest } from "@/lib/core/usecase-models/list-did-parents-usecase-models"; -import { DIDType } from "@/lib/core/entity/rucio"; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers'; +import { BaseController } from '@/lib/sdk/controller'; +import { NextApiResponse } from 'next'; +import { MockHttpStreamableResponseFactory } from 'test/fixtures/http-fixtures'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; +import { Readable } from 'stream'; +import { ListDIDParentsControllerParameters } from '@/lib/infrastructure/controller/list-did-parents-controller'; +import { ListDIDParentsRequest } from '@/lib/core/usecase-models/list-did-parents-usecase-models'; +import { DIDType } from '@/lib/core/entity/rucio'; -describe("List DID Parents Feature tests", () => { +describe('List DID Parents Feature tests', () => { beforeEach(() => { fetchMock.doMock(); const didListParentsMockEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/dids/test/file1/parents`, - method: "GET", - includes: "test/file1/parents", + method: 'GET', + includes: 'test/file1/parents', response: { status: 200, headers: { - "Content-Type": "application/x-json-stream", + 'Content-Type': 'application/x-json-stream', }, - body: Readable.from( [ - JSON.stringify({ - "scope": "test", - "name": "dataset1", - "type": "DATASET" - }), - JSON.stringify({ - "scope": "test", - "name": "dataset2", - "type": "DATASET" - }) - ].join("\n")), + body: Readable.from( + [ + JSON.stringify({ + scope: 'test', + name: 'dataset1', + type: 'DATASET', + }), + JSON.stringify({ + scope: 'test', + name: 'dataset2', + type: 'DATASET', + }), + ].join('\n'), + ), }, }; @@ -42,51 +44,52 @@ describe("List DID Parents Feature tests", () => { afterEach(() => { fetchMock.dontMock(); }); - it("should list DID parents", async () => { + it('should list DID parents', async () => { const res = MockHttpStreamableResponseFactory.getMockResponse(); - const listDIDParentsController = appContainer.get>(CONTROLLERS.LIST_DID_PARENTS); + const listDIDParentsController = appContainer.get>( + CONTROLLERS.LIST_DID_PARENTS, + ); const listDIDParentsControllerParams: ListDIDParentsControllerParameters = { response: res as unknown as NextApiResponse, rucioAuthToken: MockRucioServerFactory.VALID_RUCIO_TOKEN, name: 'file1', - scope: 'test' - } + scope: 'test', + }; await listDIDParentsController.execute(listDIDParentsControllerParams); - const receivedData: any[] = [] + const receivedData: any[] = []; const onData = (data: any) => { - receivedData.push(JSON.parse(data)) - } + receivedData.push(JSON.parse(data)); + }; const done = new Promise((resolve, reject) => { - res.on('data', onData) + res.on('data', onData); res.on('end', () => { - res.off('data', onData) - resolve() - }) + res.off('data', onData); + resolve(); + }); res.on('error', err => { - res.off('data', onData) - reject(err) - }) - }) + res.off('data', onData); + reject(err); + }); + }); - await done - console.log(receivedData) - expect(receivedData.length).toBe(2) + await done; + console.log(receivedData); + expect(receivedData.length).toBe(2); expect(receivedData[0]).toEqual({ - "status": "success", - "scope": "test", - "name": "dataset1", - "did_type": DIDType.DATASET - }) + status: 'success', + scope: 'test', + name: 'dataset1', + did_type: DIDType.DATASET, + }); expect(receivedData[1]).toEqual({ - "status": "success", - "scope": "test", - "name": "dataset2", - "did_type": DIDType.DATASET - }) - + status: 'success', + scope: 'test', + name: 'dataset2', + did_type: DIDType.DATASET, + }); }); -}); \ No newline at end of file +}); diff --git a/test/api/did/list-did-rules.test.ts b/test/api/did/list-did-rules.test.ts index a08c04ffe..d155331cc 100644 --- a/test/api/did/list-did-rules.test.ts +++ b/test/api/did/list-did-rules.test.ts @@ -1,27 +1,60 @@ -import { ListDIDRulesRequest } from "@/lib/core/usecase-models/list-did-rules-usecase-models"; -import { ListDIDRulesControllerParameters } from "@/lib/infrastructure/controller/list-did-rules-controller"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import CONTROLLERS from "@/lib/infrastructure/ioc/ioc-symbols-controllers"; -import { BaseController } from "@/lib/sdk/controller"; -import { NextApiResponse } from "next"; -import { MockHttpStreamableResponseFactory } from "test/fixtures/http-fixtures"; -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; -import { Readable } from "stream"; +import { ListDIDRulesRequest } from '@/lib/core/usecase-models/list-did-rules-usecase-models'; +import { ListDIDRulesControllerParameters } from '@/lib/infrastructure/controller/list-did-rules-controller'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers'; +import { BaseController } from '@/lib/sdk/controller'; +import { NextApiResponse } from 'next'; +import { MockHttpStreamableResponseFactory } from 'test/fixtures/http-fixtures'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; +import { Readable } from 'stream'; -describe("List DID Rules Feature tests", () => { +describe('List DID Rules Feature tests', () => { beforeEach(() => { fetchMock.doMock(); const didListRulesMockEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/dids/test/dataset1/rules`, - method: "GET", - includes: "test/dataset1/rules", + method: 'GET', + includes: 'test/dataset1/rules', response: { status: 200, headers: { - "Content-Type": "application/x-json-stream", + 'Content-Type': 'application/x-json-stream', }, - body: Readable.from( [ - JSON.stringify({"id":"dummy_id","subscription_id":"sample_subscription_007","account":"dummy_account","scope":"dummy_scope","name":"dummy_name","did_type":"DATASET","state":"OK","error":null,"rse_expression":"dummy_rse_expression","copies":1,"expires_at":null,"weight":null,"locked":true,"locks_ok_cnt":28635,"locks_replicating_cnt":0,"locks_stuck_cnt":0,"source_replica_expression":"dummy_source_replica_expression","activity":"dummy_activity","grouping":"DATASET","notification":"NO","stuck_at":null,"purge_replicas":false,"ignore_availability":true,"ignore_account_limit":false,"priority":3,"comments":null,"child_rule_id":null,"eol_at":null,"split_container":false,"meta":null,"created_at":"Fri, 09 Jun 2023 13:16:31 UTC","updated_at":"Sat, 10 Jun 2023 05:52:45 UTC"}), + body: Readable.from([ + JSON.stringify({ + id: 'dummy_id', + subscription_id: 'sample_subscription_007', + account: 'dummy_account', + scope: 'dummy_scope', + name: 'dummy_name', + did_type: 'DATASET', + state: 'OK', + error: null, + rse_expression: 'dummy_rse_expression', + copies: 1, + expires_at: null, + weight: null, + locked: true, + locks_ok_cnt: 28635, + locks_replicating_cnt: 0, + locks_stuck_cnt: 0, + source_replica_expression: 'dummy_source_replica_expression', + activity: 'dummy_activity', + grouping: 'DATASET', + notification: 'NO', + stuck_at: null, + purge_replicas: false, + ignore_availability: true, + ignore_account_limit: false, + priority: 3, + comments: null, + child_rule_id: null, + eol_at: null, + split_container: false, + meta: null, + created_at: 'Fri, 09 Jun 2023 13:16:31 UTC', + updated_at: 'Sat, 10 Jun 2023 05:52:45 UTC', + }), ]), }, }; @@ -36,69 +69,72 @@ describe("List DID Rules Feature tests", () => { 'Content-Type': 'application/x-json-stream', }, body: JSON.stringify({ - "id": "bccaabb5877a443abd6c56f3271557df", - "name": "*Functional Test", - "filter": "{\"scope\": [\"tests\"], \"project\": [\"step14\"], \"split_rule\": true}", - "replication_rules": "[{\"activity\": \"Functional Test\", \"rse_expression\": \"tier=1&type=DATADISK\", \"source_replica_expression\": \"CERN-PROD_DATADISK\", \"copies\": \"*\", \"lifetime\": 172800, \"comments\": \"Functional tests from Tier-0 to Tier-1s\"}, {\"activity\": \"Functional Test\", \"rse_expression\": \"tier=2&type=DATADISK\", \"source_replica_expression\": \"tier=1&type=DATADISK\", \"copies\": \"*\", \"lifetime\": 172800, \"comments\": \"Functional tests from Tier-1s to Tier-2s\"}, {\"activity\": \"Functional Test\", \"rse_expression\": \"type=TEST\", \"copies\": \"*\", \"lifetime\": 172800, \"comments\": \"Functional tests to RSEs of type TEST\"}]", - "policyid": 0, - "state": "UPDATED", - "last_processed": "Tue, 18 Jul 2023 12:00:30 UTC", - "account": "ddmadmin", - "lifetime": "Sun, 25 May 2042 15:41:54 UTC", - "comments": "The Automatix daemon is configured to periodically produce small datasets for testing purposes and upload them to CERN-PROD_DATADISK. This subscription creates replication rules from Tier-0 to the Tier-1 DATADISKs, from the Tier-1s to the Tier-2 DATADISKs, and from anywhere to RSEs of type TEST. All created rules and the datasets themselves have a lifetime of 2 days.", - "retroactive": false, - "expired_at": null, - "created_at": "Wed, 21 May 2014 08:40:15 UTC", - "updated_at": "Tue, 18 Jul 2023 12:00:30 UTC" - }) - } - } + id: 'bccaabb5877a443abd6c56f3271557df', + name: '*Functional Test', + filter: '{"scope": ["tests"], "project": ["step14"], "split_rule": true}', + replication_rules: + '[{"activity": "Functional Test", "rse_expression": "tier=1&type=DATADISK", "source_replica_expression": "CERN-PROD_DATADISK", "copies": "*", "lifetime": 172800, "comments": "Functional tests from Tier-0 to Tier-1s"}, {"activity": "Functional Test", "rse_expression": "tier=2&type=DATADISK", "source_replica_expression": "tier=1&type=DATADISK", "copies": "*", "lifetime": 172800, "comments": "Functional tests from Tier-1s to Tier-2s"}, {"activity": "Functional Test", "rse_expression": "type=TEST", "copies": "*", "lifetime": 172800, "comments": "Functional tests to RSEs of type TEST"}]', + policyid: 0, + state: 'UPDATED', + last_processed: 'Tue, 18 Jul 2023 12:00:30 UTC', + account: 'ddmadmin', + lifetime: 'Sun, 25 May 2042 15:41:54 UTC', + comments: + 'The Automatix daemon is configured to periodically produce small datasets for testing purposes and upload them to CERN-PROD_DATADISK. This subscription creates replication rules from Tier-0 to the Tier-1 DATADISKs, from the Tier-1s to the Tier-2 DATADISKs, and from anywhere to RSEs of type TEST. All created rules and the datasets themselves have a lifetime of 2 days.', + retroactive: false, + expired_at: null, + created_at: 'Wed, 21 May 2014 08:40:15 UTC', + updated_at: 'Tue, 18 Jul 2023 12:00:30 UTC', + }), + }, + }; MockRucioServerFactory.createMockRucioServer(true, [didListRulesMockEndpoint, getSubscriptionEndpoint]); }); afterEach(() => { fetchMock.dontMock(); }); - it("should list DID rules", async () => { + it('should list DID rules', async () => { const res = MockHttpStreamableResponseFactory.getMockResponse(); - const listDIDRulesController = appContainer.get>(CONTROLLERS.LIST_DID_RULES); + const listDIDRulesController = appContainer.get>( + CONTROLLERS.LIST_DID_RULES, + ); const listDIDRulesControllerParams: ListDIDRulesControllerParameters = { sessionAccount: 'ddmadmin', rucioAuthToken: MockRucioServerFactory.VALID_RUCIO_TOKEN, response: res as unknown as NextApiResponse, name: 'dataset1', - scope: 'test' - } + scope: 'test', + }; await listDIDRulesController.execute(listDIDRulesControllerParams); - const receivedData: any[] = [] + const receivedData: any[] = []; const onData = (data: any) => { - receivedData.push(JSON.parse(data)) - } + receivedData.push(JSON.parse(data)); + }; const done = new Promise((resolve, reject) => { - res.on('data', onData) + res.on('data', onData); res.on('end', () => { - res.off('data', onData) - resolve() - }) + res.off('data', onData); + resolve(); + }); res.on('error', err => { - res.off('data', onData) - reject(err) - }) - }) + res.off('data', onData); + reject(err); + }); + }); - await done - console.log(receivedData) - expect(receivedData.length).toBe(1) - expect(receivedData[0].id).toBe('dummy_id') + await done; + console.log(receivedData); + expect(receivedData.length).toBe(1); + expect(receivedData[0].id).toBe('dummy_id'); expect(receivedData[0].subscription).toEqual({ name: '*Functional Test', - account: 'ddmadmin' - }) - expect(receivedData[0].account).toBe('dummy_account') - + account: 'ddmadmin', + }); + expect(receivedData[0].account).toBe('dummy_account'); }); -}); \ No newline at end of file +}); diff --git a/test/api/did/list-dids-stream-error.test.ts b/test/api/did/list-dids-stream-error.test.ts index efc74cb87..d0c89e69f 100644 --- a/test/api/did/list-dids-stream-error.test.ts +++ b/test/api/did/list-dids-stream-error.test.ts @@ -1,16 +1,16 @@ -import { BaseController } from '@/lib/sdk/controller' -import { ListDIDsRequest } from '@/lib/core/usecase-models/list-dids-usecase-models' -import appContainer from '@/lib/infrastructure/ioc/container-config' -import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers' -import { ListDIDsControllerParameters } from '@/lib/infrastructure/controller/list-dids-controller' -import { NextApiResponse } from 'next' -import { Readable } from 'stream' -import { MockHttpStreamableResponseFactory } from 'test/fixtures/http-fixtures' -import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server' +import { BaseController } from '@/lib/sdk/controller'; +import { ListDIDsRequest } from '@/lib/core/usecase-models/list-dids-usecase-models'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers'; +import { ListDIDsControllerParameters } from '@/lib/infrastructure/controller/list-dids-controller'; +import { NextApiResponse } from 'next'; +import { Readable } from 'stream'; +import { MockHttpStreamableResponseFactory } from 'test/fixtures/http-fixtures'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; describe('DID API Tests #2', () => { beforeEach(() => { - fetchMock.doMock() + fetchMock.doMock(); const listDIDsEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/dids/test/dids/search`, method: 'GET', @@ -20,17 +20,9 @@ describe('DID API Tests #2', () => { headers: { 'Content-Type': 'application/x-json-stream', }, - body: Readable.from( - [ - '"dataset1"\n', - '"dataset2"\n', - '"dataset3"\n', - " ", - " ", - ].join('\n'), - ), + body: Readable.from(['"dataset1"\n', '"dataset2"\n', '"dataset3"\n', ' ', ' '].join('\n')), }, - } + }; const dataset1StatusEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/dids/test/dataset1/status?dynamic_depth=FILE`, @@ -52,7 +44,7 @@ describe('DID API Tests #2', () => { bytes: 0, }), }, - } + }; const dataset2StatusEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/dids/test/dataset2/status?dynamic_depth=FILE`, @@ -74,7 +66,7 @@ describe('DID API Tests #2', () => { length: 456, }), }, - } + }; const dataset3StatusEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/dids/test/dataset3/status?dynamic_depth=FILE`, @@ -96,82 +88,77 @@ describe('DID API Tests #2', () => { length: 789, }), }, - } + }; MockRucioServerFactory.createMockRucioServer(true, [ listDIDsEndpoint, dataset1StatusEndpoint, dataset2StatusEndpoint, dataset3StatusEndpoint, - ]) - }) + ]); + }); afterEach(() => { - fetchMock.dontMock() - }) + fetchMock.dontMock(); + }); it('Should successfully stream DIDs', async () => { - const res = MockHttpStreamableResponseFactory.getMockResponse() - const listDIDsController = appContainer.get>( - CONTROLLERS.LIST_DIDS, - ) + const res = MockHttpStreamableResponseFactory.getMockResponse(); + const listDIDsController = appContainer.get>(CONTROLLERS.LIST_DIDS); const controllerParams: ListDIDsControllerParameters = { response: res as unknown as NextApiResponse, rucioAuthToken: MockRucioServerFactory.VALID_RUCIO_TOKEN, - query: "test:dataset1", - type: "dataset" - } - await listDIDsController.execute( - controllerParams, - ) + query: 'test:dataset1', + type: 'dataset', + }; + await listDIDsController.execute(controllerParams); - const receivedData: any[] = [] + const receivedData: any[] = []; const onData = (data: any) => { - receivedData.push(JSON.parse(data)) - } + receivedData.push(JSON.parse(data)); + }; const done = new Promise((resolve, reject) => { - res.on('data', onData) + res.on('data', onData); res.on('end', () => { - res.off('data', onData) - resolve() - }) + res.off('data', onData); + resolve(); + }); res.on('error', err => { - res.off('data', onData) - reject(err) - }) - }) - - await done + res.off('data', onData); + reject(err); + }); + }); + await done; expect(receivedData).toEqual([ { - "status": "success", - "name": "dataset1", - "scope": "test", - "did_type": "Dataset", - "bytes": 0, - "length": 0, - "open": true, + status: 'success', + name: 'dataset1', + scope: 'test', + did_type: 'Dataset', + bytes: 0, + length: 0, + open: true, }, { - "status": "success", - "name": "dataset2", - "scope": "test", - "did_type": "Dataset", - "bytes": 123, - "length": 456, - "open": true, + status: 'success', + name: 'dataset2', + scope: 'test', + did_type: 'Dataset', + bytes: 123, + length: 456, + open: true, }, { - "status": "success", - "name": "dataset3", - "scope": "test", - "did_type": "Dataset", - "bytes": 456, - "length": 789, - "open": true, - } - ]) - }) -}) + status: 'success', + name: 'dataset3', + scope: 'test', + did_type: 'Dataset', + bytes: 456, + length: 789, + open: true, + }, + ]); + }); +}); diff --git a/test/api/did/list-dids.test.ts b/test/api/did/list-dids.test.ts index 3a39472b3..6e7234124 100644 --- a/test/api/did/list-dids.test.ts +++ b/test/api/did/list-dids.test.ts @@ -1,16 +1,16 @@ -import { BaseController } from '@/lib/sdk/controller' -import { ListDIDsRequest } from '@/lib/core/usecase-models/list-dids-usecase-models' -import appContainer from '@/lib/infrastructure/ioc/container-config' -import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers' -import { ListDIDsControllerParameters } from '@/lib/infrastructure/controller/list-dids-controller' -import { NextApiResponse } from 'next' -import { Readable } from 'stream' -import { MockHttpStreamableResponseFactory } from 'test/fixtures/http-fixtures' -import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server' +import { BaseController } from '@/lib/sdk/controller'; +import { ListDIDsRequest } from '@/lib/core/usecase-models/list-dids-usecase-models'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers'; +import { ListDIDsControllerParameters } from '@/lib/infrastructure/controller/list-dids-controller'; +import { NextApiResponse } from 'next'; +import { Readable } from 'stream'; +import { MockHttpStreamableResponseFactory } from 'test/fixtures/http-fixtures'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; describe('DID API Tests', () => { beforeEach(() => { - fetchMock.doMock() + fetchMock.doMock(); const listDIDsEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/dids/test/dids/search`, method: 'GET', @@ -20,15 +20,9 @@ describe('DID API Tests', () => { headers: { 'Content-Type': 'application/x-json-stream', }, - body: Readable.from( - [ - '"dataset1"\n', - '"dataset2"\n', - '"dataset3"\n', - ].join('\n'), - ), + body: Readable.from(['"dataset1"\n', '"dataset2"\n', '"dataset3"\n'].join('\n')), }, - } + }; const dataset1StatusEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/dids/test/dataset1/status?dynamic_depth=FILE`, @@ -50,7 +44,7 @@ describe('DID API Tests', () => { bytes: 0, }), }, - } + }; const dataset2StatusEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/dids/test/dataset2/status?dynamic_depth=FILE`, @@ -72,7 +66,7 @@ describe('DID API Tests', () => { length: 456, }), }, - } + }; const dataset3StatusEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/dids/test/dataset3/status?dynamic_depth=FILE`, @@ -94,82 +88,77 @@ describe('DID API Tests', () => { length: 789, }), }, - } + }; MockRucioServerFactory.createMockRucioServer(true, [ listDIDsEndpoint, dataset1StatusEndpoint, dataset2StatusEndpoint, dataset3StatusEndpoint, - ]) - }) + ]); + }); afterEach(() => { - fetchMock.dontMock() - }) + fetchMock.dontMock(); + }); it('Should successfully stream DIDs', async () => { - const res = MockHttpStreamableResponseFactory.getMockResponse() - const listDIDsController = appContainer.get>( - CONTROLLERS.LIST_DIDS, - ) + const res = MockHttpStreamableResponseFactory.getMockResponse(); + const listDIDsController = appContainer.get>(CONTROLLERS.LIST_DIDS); const controllerParams: ListDIDsControllerParameters = { response: res as unknown as NextApiResponse, rucioAuthToken: MockRucioServerFactory.VALID_RUCIO_TOKEN, - query: "test:dataset1", - type: "dataset" - } - await listDIDsController.execute( - controllerParams, - ) + query: 'test:dataset1', + type: 'dataset', + }; + await listDIDsController.execute(controllerParams); - const receivedData: any[] = [] + const receivedData: any[] = []; const onData = (data: any) => { - receivedData.push(JSON.parse(data)) - } + receivedData.push(JSON.parse(data)); + }; const done = new Promise((resolve, reject) => { - res.on('data', onData) + res.on('data', onData); res.on('end', () => { - res.off('data', onData) - resolve() - }) + res.off('data', onData); + resolve(); + }); res.on('error', err => { - res.off('data', onData) - reject(err) - }) - }) - - await done + res.off('data', onData); + reject(err); + }); + }); + await done; expect(receivedData).toEqual([ { - "status": "success", - "name": "dataset1", - "scope": "test", - "did_type": "Dataset", - "bytes": 0, - "length": 0, - "open": true, + status: 'success', + name: 'dataset1', + scope: 'test', + did_type: 'Dataset', + bytes: 0, + length: 0, + open: true, }, { - "status": "success", - "name": "dataset2", - "scope": "test", - "did_type": "Dataset", - "bytes": 123, - "length": 456, - "open": true, + status: 'success', + name: 'dataset2', + scope: 'test', + did_type: 'Dataset', + bytes: 123, + length: 456, + open: true, }, { - "status": "success", - "name": "dataset3", - "scope": "test", - "did_type": "Dataset", - "bytes": 456, - "length": 789, - "open": true, - } - ]) - }) -}) + status: 'success', + name: 'dataset3', + scope: 'test', + did_type: 'Dataset', + bytes: 456, + length: 789, + open: true, + }, + ]); + }); +}); diff --git a/test/api/get-site-header.test.ts b/test/api/get-site-header.test.ts index ade59fc0e..7436cf03c 100644 --- a/test/api/get-site-header.test.ts +++ b/test/api/get-site-header.test.ts @@ -1,14 +1,14 @@ -import { SessionUser } from "@/lib/core/entity/auth-models"; -import { addOrUpdateSessionUser, setEmptySession } from "@/lib/infrastructure/auth/session-utils"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import CONTROLLERS from "@/lib/infrastructure/ioc/ioc-symbols-controllers"; -import GetSiteHeaderController from "@/lib/infrastructure/controller/get-site-header-controller"; -import { GetSiteHeaderControllerParameters } from "@/lib/infrastructure/controller/get-site-header-controller"; -import { SiteHeaderViewModel } from "@/lib/infrastructure/data/view-model/site-header"; -import { getIronSession } from "iron-session"; -import { NextApiRequest, NextApiResponse } from "next"; -import { createMocks } from "node-mocks-http"; -import { createHttpMocks } from "test/fixtures/http-fixtures"; +import { SessionUser } from '@/lib/core/entity/auth-models'; +import { addOrUpdateSessionUser, setEmptySession } from '@/lib/infrastructure/auth/session-utils'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers'; +import GetSiteHeaderController from '@/lib/infrastructure/controller/get-site-header-controller'; +import { GetSiteHeaderControllerParameters } from '@/lib/infrastructure/controller/get-site-header-controller'; +import { SiteHeaderViewModel } from '@/lib/infrastructure/data/view-model/site-header'; +import { getIronSession } from 'iron-session'; +import { NextApiRequest, NextApiResponse } from 'next'; +import { createMocks } from 'node-mocks-http'; +import { createHttpMocks } from 'test/fixtures/http-fixtures'; describe('Get SiteHeader API Test', () => { it('should present successful SiteHeaderViewModel', async () => { @@ -21,11 +21,11 @@ describe('Get SiteHeader API Test', () => { cookieOptions: { secure: false, }, - }) + }); + + process.env['PROJECT_URL'] = 'https://atlas.cern'; - process.env['PROJECT_URL'] = 'https://atlas.cern' - - await setEmptySession(session, true) + await setEmptySession(session, true); await addOrUpdateSessionUser(session, { rucioIdentity: 'ddmlab', rucioAccount: 'root', @@ -34,13 +34,13 @@ describe('Get SiteHeader API Test', () => { rucioAuthType: 'userpass', rucioOIDCProvider: '', rucioVO: 'def', - } as SessionUser) + } as SessionUser); - const getSiteHeaderController = appContainer.get(CONTROLLERS.GET_SITE_HEADER) + const getSiteHeaderController = appContainer.get(CONTROLLERS.GET_SITE_HEADER); const getSiteHeaderControllerParameters = { session: session, response: res as unknown as NextApiResponse, - } + }; await getSiteHeaderController.execute(getSiteHeaderControllerParameters); expect(res._getStatusCode()).toBe(200); @@ -49,30 +49,28 @@ describe('Get SiteHeader API Test', () => { expect(viewModel.projectUrl).toBe('https://atlas.cern'); expect(viewModel).toHaveProperty('activeAccount'); expect(viewModel.activeAccount?.rucioIdentity).toBe('ddmlab'); - expect(viewModel.homeUrl).toBe('/dashboard') + expect(viewModel.homeUrl).toBe('/dashboard'); - delete process.env['PROJECT_URL'] - }) + delete process.env['PROJECT_URL']; + }); it('should present SiteHeaderViewModel when Session does not contain any users', async () => { - const { req, res, session } = await createHttpMocks() - const siteHeaderController = appContainer.get(CONTROLLERS.GET_SITE_HEADER) + const { req, res, session } = await createHttpMocks(); + const siteHeaderController = appContainer.get(CONTROLLERS.GET_SITE_HEADER); await siteHeaderController.execute({ session: session, response: res as unknown as NextApiResponse, }); - + expect(res._getStatusCode()).toBe(418); const data = JSON.parse(res._getData()); - expect(data.message).toBe('no-active-user') + expect(data.message).toBe('no-active-user'); expect(data).not.toHaveProperty('projectUrl'); expect(data).not.toHaveProperty('activeAccount'); expect(data).toHaveProperty('homeUrl'); - expect(data.homeUrl).toBe('/dashboard') - - expect(session.user).toBeUndefined() - expect(session.allUsers).toBeUndefined() - - }) + expect(data.homeUrl).toBe('/dashboard'); -}) \ No newline at end of file + expect(session.user).toBeUndefined(); + expect(session.allUsers).toBeUndefined(); + }); +}); diff --git a/test/api/jest.api.setup.ts b/test/api/jest.api.setup.ts index 754e53354..9735fa42a 100644 --- a/test/api/jest.api.setup.ts +++ b/test/api/jest.api.setup.ts @@ -1,9 +1,9 @@ -import '@testing-library/jest-dom/extend-expect' -import "reflect-metadata" -import fetchMock from 'jest-fetch-mock' -import "@inrupt/jest-jsdom-polyfills" -fetchMock.enableMocks() +import '@testing-library/jest-dom/extend-expect'; +import 'reflect-metadata'; +import fetchMock from 'jest-fetch-mock'; +import '@inrupt/jest-jsdom-polyfills'; +fetchMock.enableMocks(); // import { TextEncoder, TextDecoder } from 'util'; // global.TextEncoder = TextEncoder; -// global.TextDecoder = TextDecoder; \ No newline at end of file +// global.TextDecoder = TextDecoder; diff --git a/test/api/replica/list-dataset-replicas.test.ts b/test/api/replica/list-dataset-replicas.test.ts index b7ce0477b..089b76225 100644 --- a/test/api/replica/list-dataset-replicas.test.ts +++ b/test/api/replica/list-dataset-replicas.test.ts @@ -1,19 +1,19 @@ -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server" -import { Readable } from "stream" -import ListDatasetReplicasController, { ListDatasetReplicasControllerParameters } from "@/lib/infrastructure/controller/list-dataset-replicas-controller" -import appContainer from "@/lib/infrastructure/ioc/container-config" -import { BaseController } from "@/lib/sdk/controller" -import { ListDatasetReplicasRequest } from "@/lib/core/usecase-models/list-dataset-replicas-usecase-models" -import CONTROLLERS from "@/lib/infrastructure/ioc/ioc-symbols-controllers" -import { MockHttpStreamableResponseFactory } from "test/fixtures/http-fixtures" -import { NextApiResponse } from "next" -import { DIDDatasetReplicasViewModel } from "@/lib/infrastructure/data/view-model/did" +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; +import { Readable } from 'stream'; +import ListDatasetReplicasController, { + ListDatasetReplicasControllerParameters, +} from '@/lib/infrastructure/controller/list-dataset-replicas-controller'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import { BaseController } from '@/lib/sdk/controller'; +import { ListDatasetReplicasRequest } from '@/lib/core/usecase-models/list-dataset-replicas-usecase-models'; +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers'; +import { MockHttpStreamableResponseFactory } from 'test/fixtures/http-fixtures'; +import { NextApiResponse } from 'next'; +import { DIDDatasetReplicasViewModel } from '@/lib/infrastructure/data/view-model/did'; - -describe("List Dataset Replicas Feature Tests", () => { - +describe('List Dataset Replicas Feature Tests', () => { beforeEach(() => { - fetchMock.doMock() + fetchMock.doMock(); const listDatasetReplicasEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/replicas/test/dataset1/datasets`, method: 'GET', @@ -26,71 +26,70 @@ describe("List Dataset Replicas Feature Tests", () => { body: Readable.from( [ JSON.stringify({ - "scope": "test", - "name": "dataset1", - "rse": "XRD3", - "rse_id": "28e77f4f2c864f7d949eb602d6f05985", - "bytes": 0, - "length": 0, - "available_bytes": 1000, - "available_length": 10, - "state": "UNAVAILABLE", - "created_at": "Tue, 12 Sep 2023 09:12:11 UTC", - "updated_at": "Tue, 12 Sep 2023 09:12:11 UTC", - "accessed_at": null - }), - ].join('\n') - ) - } - } - MockRucioServerFactory.createMockRucioServer(true, [listDatasetReplicasEndpoint]) - }) - + scope: 'test', + name: 'dataset1', + rse: 'XRD3', + rse_id: '28e77f4f2c864f7d949eb602d6f05985', + bytes: 0, + length: 0, + available_bytes: 1000, + available_length: 10, + state: 'UNAVAILABLE', + created_at: 'Tue, 12 Sep 2023 09:12:11 UTC', + updated_at: 'Tue, 12 Sep 2023 09:12:11 UTC', + accessed_at: null, + }), + ].join('\n'), + ), + }, + }; + MockRucioServerFactory.createMockRucioServer(true, [listDatasetReplicasEndpoint]); + }); + afterEach(() => { - fetchMock.resetMocks() - }) + fetchMock.resetMocks(); + }); it('should successfully stream a list of dataset replicas view models', async () => { const res = MockHttpStreamableResponseFactory.getMockResponse(); - const listDatasetReplicasController: ListDatasetReplicasController = appContainer.get(CONTROLLERS.LIST_DATASET_REPLICAS) - + const listDatasetReplicasController: ListDatasetReplicasController = appContainer.get(CONTROLLERS.LIST_DATASET_REPLICAS); + const controllerParameters: ListDatasetReplicasControllerParameters = { response: res as unknown as NextApiResponse, rucioAuthToken: MockRucioServerFactory.VALID_RUCIO_TOKEN, scope: 'test', name: 'dataset1', - } - await listDatasetReplicasController.execute(controllerParameters) - const receivedData: any[] = [] + }; + await listDatasetReplicasController.execute(controllerParameters); + const receivedData: any[] = []; const onData = (data: any) => { - receivedData.push(JSON.parse(data)) - } + receivedData.push(JSON.parse(data)); + }; const done = new Promise((resolve, reject) => { - res.on('data', onData) + res.on('data', onData); res.on('end', () => { - res.off('data', onData) - resolve() - }) + res.off('data', onData); + resolve(); + }); res.on('error', err => { - res.off('data', onData) - reject(err) - }) - }) + res.off('data', onData); + reject(err); + }); + }); - await done - console.log(receivedData) - expect(receivedData.length).toBe(1) + await done; + console.log(receivedData); + expect(receivedData.length).toBe(1); expect(receivedData[0]).toEqual({ - "status": 'success', - "rseblocked": 0, - "rse": 'XRD3', - "availability": false, - "available_files": 10, - "available_bytes": 1000, - "creation_date": "Tue, 12 Sep 2023 09:12:11 UTC", - "last_accessed": "", - } as DIDDatasetReplicasViewModel) - }) - -}) \ No newline at end of file + status: 'success', + rseblocked: 0, + rse: 'XRD3', + availability: false, + available_files: 10, + available_bytes: 1000, + creation_date: 'Tue, 12 Sep 2023 09:12:11 UTC', + last_accessed: '', + } as DIDDatasetReplicasViewModel); + }); +}); diff --git a/test/api/replica/list-file-replicas.test.ts b/test/api/replica/list-file-replicas.test.ts index 79a988b74..2fe0617ae 100644 --- a/test/api/replica/list-file-replicas.test.ts +++ b/test/api/replica/list-file-replicas.test.ts @@ -1,17 +1,17 @@ -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import CONTROLLERS from "@/lib/infrastructure/ioc/ioc-symbols-controllers"; -import { BaseController } from "@/lib/sdk/controller"; -import { NextApiResponse } from "next"; -import { MockHttpStreamableResponseFactory } from "test/fixtures/http-fixtures"; -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; -import { Readable } from "stream"; -import { ListFileReplicasRequest } from "@/lib/core/usecase-models/list-file-replicas-usecase-models"; -import { ListFileReplicasControllerParameters } from "@/lib/infrastructure/controller/list-file-replicas-controller"; -import { ReplicaState } from "@/lib/core/entity/rucio"; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers'; +import { BaseController } from '@/lib/sdk/controller'; +import { NextApiResponse } from 'next'; +import { MockHttpStreamableResponseFactory } from 'test/fixtures/http-fixtures'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; +import { Readable } from 'stream'; +import { ListFileReplicasRequest } from '@/lib/core/usecase-models/list-file-replicas-usecase-models'; +import { ListFileReplicasControllerParameters } from '@/lib/infrastructure/controller/list-file-replicas-controller'; +import { ReplicaState } from '@/lib/core/entity/rucio'; -describe("List File Replicas Feature tests", () => { +describe('List File Replicas Feature tests', () => { beforeEach(() => { - fetchMock.doMock() + fetchMock.doMock(); const listFileReplicasEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/replicas/list`, method: 'POST', @@ -24,74 +24,72 @@ describe("List File Replicas Feature tests", () => { body: Readable.from( [ JSON.stringify({ - "scope": "test", - "name": "file1", - "rses": { - "XRD3": [ - "root://xrd3:1096//rucio/test/80/25/file1" - ], - "XRD1": [ - "root://xrd1:1094//rucio/test/80/25/file1" - ] + scope: 'test', + name: 'file1', + rses: { + XRD3: ['root://xrd3:1096//rucio/test/80/25/file1'], + XRD1: ['root://xrd1:1094//rucio/test/80/25/file1'], + }, + states: { + XRD3: 'COPYING', + XRD1: 'AVAILABLE', }, - "states": { - "XRD3": "COPYING", - "XRD1": "AVAILABLE" - } }), - ].join('\n') - ) - } - } - MockRucioServerFactory.createMockRucioServer(true, [listFileReplicasEndpoint]) + ].join('\n'), + ), + }, + }; + MockRucioServerFactory.createMockRucioServer(true, [listFileReplicasEndpoint]); }); afterEach(() => { fetchMock.dontMock(); }); - it("should list File replicase for given FILE DID", async () => { + it('should list File replicase for given FILE DID', async () => { const res = MockHttpStreamableResponseFactory.getMockResponse(); - const listFileReplicasController = appContainer.get>(CONTROLLERS.LIST_FILE_REPLICAS); + const listFileReplicasController = appContainer.get>( + CONTROLLERS.LIST_FILE_REPLICAS, + ); const listFileReplicasControllerParams: ListFileReplicasControllerParameters = { response: res as unknown as NextApiResponse, rucioAuthToken: MockRucioServerFactory.VALID_RUCIO_TOKEN, name: 'file1', - scope: 'test' - } + scope: 'test', + }; await listFileReplicasController.execute(listFileReplicasControllerParams); - const receivedData: any[] = [] + const receivedData: any[] = []; const onData = (data: any) => { - receivedData.push(JSON.parse(data)) - } + receivedData.push(JSON.parse(data)); + }; const done = new Promise((resolve, reject) => { - res.on('data', onData) + res.on('data', onData); res.on('end', () => { - res.off('data', onData) - resolve() - }) + res.off('data', onData); + resolve(); + }); res.on('error', err => { - res.off('data', onData) - reject(err) - }) - }) + res.off('data', onData); + reject(err); + }); + }); - await done - console.log(receivedData) - expect(receivedData.length).toBe(2) + await done; + console.log(receivedData); + expect(receivedData.length).toBe(2); expect(receivedData[0]).toEqual({ - "status": "success", - "rse": "XRD3", - "state": ReplicaState.COPYING - }) + status: 'success', + rse: 'XRD3', + state: ReplicaState.COPYING, + }); expect(receivedData[1]).toEqual({ - "status": "success", - "rse": "XRD1", - "state": ReplicaState.AVAILABLE - }) + status: 'success', + rse: 'XRD1', + state: ReplicaState.AVAILABLE, + }); }); -}); \ No newline at end of file +}); diff --git a/test/api/rse/get-rse-attributes.test.ts b/test/api/rse/get-rse-attributes.test.ts index 16a4a9df2..d545e0d1a 100644 --- a/test/api/rse/get-rse-attributes.test.ts +++ b/test/api/rse/get-rse-attributes.test.ts @@ -1,14 +1,14 @@ -import { GetRSEAttributesRequest } from "@/lib/core/usecase-models/get-rse-attributes-usecase-models"; -import { GetRSERequest } from "@/lib/core/usecase-models/get-rse-usecase-models"; -import { GetRSEAttributesControllerParameters } from "@/lib/infrastructure/controller/get-rse-attributes-controller"; -import { GetRSEControllerParameters } from "@/lib/infrastructure/controller/get-rse-controller"; -import { RSEAttributeViewModel, RSEViewModel } from "@/lib/infrastructure/data/view-model/rse"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import CONTROLLERS from "@/lib/infrastructure/ioc/ioc-symbols-controllers"; -import { BaseController } from "@/lib/sdk/controller"; -import { NextApiResponse } from "next"; -import { createHttpMocks } from "test/fixtures/http-fixtures"; -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; +import { GetRSEAttributesRequest } from '@/lib/core/usecase-models/get-rse-attributes-usecase-models'; +import { GetRSERequest } from '@/lib/core/usecase-models/get-rse-usecase-models'; +import { GetRSEAttributesControllerParameters } from '@/lib/infrastructure/controller/get-rse-attributes-controller'; +import { GetRSEControllerParameters } from '@/lib/infrastructure/controller/get-rse-controller'; +import { RSEAttributeViewModel, RSEViewModel } from '@/lib/infrastructure/data/view-model/rse'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers'; +import { BaseController } from '@/lib/sdk/controller'; +import { NextApiResponse } from 'next'; +import { createHttpMocks } from 'test/fixtures/http-fixtures'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; describe('GET RSE Attributes API Test', () => { beforeEach(() => { @@ -23,62 +23,62 @@ describe('GET RSE Attributes API Test', () => { 'Content-Type': 'application/json', }, body: JSON.stringify({ - "ISP": "CERN- LHC", - "MOCK3": true, - "continent": "EU", - "country_name": "Switzerland", - "region_code": "07", - "time_zone": "Europe/Zurich" - }) - } - } + ISP: 'CERN- LHC', + MOCK3: true, + continent: 'EU', + country_name: 'Switzerland', + region_code: '07', + time_zone: 'Europe/Zurich', + }), + }, + }; MockRucioServerFactory.createMockRucioServer(true, [getRSEAttributesMockEndpoint]); - }) + }); afterEach(() => { fetchMock.dontMock(); - }) + }); test('it should get attributes for an RSE', async () => { const { req, res, session } = await createHttpMocks('/api/feature/get-rse?rseName=DINGDONGRSE', 'GET', {}); - const controller = appContainer.get>(CONTROLLERS.GET_RSE_ATTRIBUTES) + const controller = appContainer.get>( + CONTROLLERS.GET_RSE_ATTRIBUTES, + ); const controllerParameters: GetRSEControllerParameters = { rucioAuthToken: MockRucioServerFactory.VALID_RUCIO_TOKEN, response: res as unknown as NextApiResponse, rseName: 'MOCK3', - } - await controller.execute(controllerParameters) - const data = await res._getJSONData() + }; + await controller.execute(controllerParameters); + const data = await res._getJSONData(); expect(data).toEqual({ status: 'success', attributes: [ { key: 'ISP', - value: 'CERN- LHC' + value: 'CERN- LHC', }, { key: 'MOCK3', - value: true + value: true, }, { key: 'continent', - value: 'EU' + value: 'EU', }, { key: 'country_name', - value: 'Switzerland' + value: 'Switzerland', }, { key: 'region_code', - value: '07' + value: '07', }, { key: 'time_zone', - value: 'Europe/Zurich' - } - ] - - - } as RSEAttributeViewModel) - }) -}) \ No newline at end of file + value: 'Europe/Zurich', + }, + ], + } as RSEAttributeViewModel); + }); +}); diff --git a/test/api/rse/get-rse-protocols.test.ts b/test/api/rse/get-rse-protocols.test.ts index 8b7c252ae..8913908c2 100644 --- a/test/api/rse/get-rse-protocols.test.ts +++ b/test/api/rse/get-rse-protocols.test.ts @@ -1,14 +1,14 @@ -import { GetRSEProtocolsRequest } from "@/lib/core/usecase-models/get-rse-protocols-usecase-models"; -import { GetRSERequest } from "@/lib/core/usecase-models/get-rse-usecase-models"; -import { GetRSEControllerParameters } from "@/lib/infrastructure/controller/get-rse-controller"; -import GetRSEProtocolsController, { GetRSEProtocolsControllerParameters } from "@/lib/infrastructure/controller/get-rse-protocols-controller"; -import { RSEViewModel } from "@/lib/infrastructure/data/view-model/rse"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import CONTROLLERS from "@/lib/infrastructure/ioc/ioc-symbols-controllers"; -import { BaseController } from "@/lib/sdk/controller"; -import { NextApiResponse } from "next"; -import { createHttpMocks } from "test/fixtures/http-fixtures"; -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; +import { GetRSEProtocolsRequest } from '@/lib/core/usecase-models/get-rse-protocols-usecase-models'; +import { GetRSERequest } from '@/lib/core/usecase-models/get-rse-usecase-models'; +import { GetRSEControllerParameters } from '@/lib/infrastructure/controller/get-rse-controller'; +import GetRSEProtocolsController, { GetRSEProtocolsControllerParameters } from '@/lib/infrastructure/controller/get-rse-protocols-controller'; +import { RSEViewModel } from '@/lib/infrastructure/data/view-model/rse'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers'; +import { BaseController } from '@/lib/sdk/controller'; +import { NextApiResponse } from 'next'; +import { createHttpMocks } from 'test/fixtures/http-fixtures'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; describe('GET RSE Protocols API Test', () => { beforeEach(() => { @@ -24,160 +24,161 @@ describe('GET RSE Protocols API Test', () => { }, body: JSON.stringify([ { - "domains": { - "lan": { - "delete": 1, - "read": 1, - "write": 1 + domains: { + lan: { + delete: 1, + read: 1, + write: 1, + }, + wan: { + delete: 1, + read: 1, + third_party_copy_read: 0, + third_party_copy_write: 0, + write: 1, + }, }, - "wan": { - "delete": 1, - "read": 1, - "third_party_copy_read": 0, - "third_party_copy_write": 0, - "write": 1 - } - }, - "extended_attributes": { - "space_token": "ATLASDATATAPE", - "web_service_path": "/srm/managerv2?SFN=" - }, - "hostname": "localhost", - "impl": "rucio.rse.protocols.posix.Default", - "port": 0, - "prefix": "/tmp/rucio_rse/", - "scheme": "file" + extended_attributes: { + space_token: 'ATLASDATATAPE', + web_service_path: '/srm/managerv2?SFN=', + }, + hostname: 'localhost', + impl: 'rucio.rse.protocols.posix.Default', + port: 0, + prefix: '/tmp/rucio_rse/', + scheme: 'file', }, { - "domains": { - "lan": { - "delete": 1, - "read": 1, - "write": 1 + domains: { + lan: { + delete: 1, + read: 1, + write: 1, + }, + wan: { + delete: 1, + read: 1, + third_party_copy_read: 0, + third_party_copy_write: 0, + write: 1, + }, }, - "wan": { - "delete": 1, - "read": 1, - "third_party_copy_read": 0, - "third_party_copy_write": 0, - "write": 1 - } - }, - "extended_attributes": null, - "hostname": "mock3.com", - "impl": "rucio.rse.protocols.webdav.Default", - "port": 2880, - "prefix": "/pnfs/rucio/disk-only/scratchdisk/", - "scheme": "https" + extended_attributes: null, + hostname: 'mock3.com', + impl: 'rucio.rse.protocols.webdav.Default', + port: 2880, + prefix: '/pnfs/rucio/disk-only/scratchdisk/', + scheme: 'https', }, { - "domains": { - "lan": { - "delete": 1, - "read": 1, - "write": 1 + domains: { + lan: { + delete: 1, + read: 1, + write: 1, + }, + wan: { + delete: 1, + read: 1, + third_party_copy_read: 1, + third_party_copy_write: 1, + write: 1, + }, + }, + extended_attributes: { + space_token: 'RUCIODISK', + web_service_path: '/srm/managerv2?SFN=', }, - "wan": { - "delete": 1, - "read": 1, - "third_party_copy_read": 1, - "third_party_copy_write": 1, - "write": 1 - } - }, - "extended_attributes": { - "space_token": "RUCIODISK", - "web_service_path": "/srm/managerv2?SFN=" - }, - "hostname": "mock3.com", - "impl": "rucio.rse.protocols.srm.Default", - "port": 8443, - "prefix": "/rucio/tmpdisk/rucio_tests/", - "scheme": "srm" - } - ]) - } - } + hostname: 'mock3.com', + impl: 'rucio.rse.protocols.srm.Default', + port: 8443, + prefix: '/rucio/tmpdisk/rucio_tests/', + scheme: 'srm', + }, + ]), + }, + }; MockRucioServerFactory.createMockRucioServer(true, [getRSEProtocolsMockEndpoint]); - }) + }); afterEach(() => { fetchMock.dontMock(); - }) + }); test('it should get RSEProtcols for an RSE', async () => { const { req, res, session } = await createHttpMocks('/api/feature/get-rse?rseName=DINGDONGRSE', 'GET', {}); - const getRSEProtocolsController = appContainer.get>(CONTROLLERS.GET_RSE_PROTOCOLS) + const getRSEProtocolsController = appContainer.get>( + CONTROLLERS.GET_RSE_PROTOCOLS, + ); const getRSEProtocolsControllerParameters: GetRSEProtocolsControllerParameters = { rucioAuthToken: MockRucioServerFactory.VALID_RUCIO_TOKEN, response: res as unknown as NextApiResponse, rseName: 'MOCK3', - } - await getRSEProtocolsController.execute(getRSEProtocolsControllerParameters) - const data = await res._getJSONData() + }; + await getRSEProtocolsController.execute(getRSEProtocolsControllerParameters); + const data = await res._getJSONData(); expect(data.protocols).toEqual([ { - "rseid": "MOCK3", - "scheme": "file", - "hostname": "localhost", - "port": 0, - "prefix": "/tmp/rucio_rse/", - "impl": "rucio.rse.protocols.posix.Default", - "priorities_lan": { - "read": 1, - "write": 1, - "delete": 1 + rseid: 'MOCK3', + scheme: 'file', + hostname: 'localhost', + port: 0, + prefix: '/tmp/rucio_rse/', + impl: 'rucio.rse.protocols.posix.Default', + priorities_lan: { + read: 1, + write: 1, + delete: 1, }, - "priorities_wan": { - "read": 1, - "write": 1, - "delete": 1, - "tpcread": 0, - "tpcwrite": 0 + priorities_wan: { + read: 1, + write: 1, + delete: 1, + tpcread: 0, + tpcwrite: 0, }, - }, - { - "rseid": "MOCK3", - "scheme": "https", - "hostname": "mock3.com", - "port": 2880, - "prefix": "/pnfs/rucio/disk-only/scratchdisk/", - "impl": "rucio.rse.protocols.webdav.Default", - "priorities_lan": { - "read": 1, - "write": 1, - "delete": 1 + }, + { + rseid: 'MOCK3', + scheme: 'https', + hostname: 'mock3.com', + port: 2880, + prefix: '/pnfs/rucio/disk-only/scratchdisk/', + impl: 'rucio.rse.protocols.webdav.Default', + priorities_lan: { + read: 1, + write: 1, + delete: 1, }, - "priorities_wan": { - "read": 1, - "write": 1, - "delete": 1, - "tpcread": 0, - "tpcwrite": 0 + priorities_wan: { + read: 1, + write: 1, + delete: 1, + tpcread: 0, + tpcwrite: 0, }, - }, - { - "rseid": "MOCK3", - "scheme": "srm", - "hostname": "mock3.com", - "port": 8443, - "prefix": "/rucio/tmpdisk/rucio_tests/", - "impl": "rucio.rse.protocols.srm.Default", - "priorities_lan": { - "read": 1, - "write": 1, - "delete": 1 + }, + { + rseid: 'MOCK3', + scheme: 'srm', + hostname: 'mock3.com', + port: 8443, + prefix: '/rucio/tmpdisk/rucio_tests/', + impl: 'rucio.rse.protocols.srm.Default', + priorities_lan: { + read: 1, + write: 1, + delete: 1, }, - "priorities_wan": { - "read": 1, - "write": 1, - "delete": 1, - "tpcread": 1, - "tpcwrite": 1 + priorities_wan: { + read: 1, + write: 1, + delete: 1, + tpcread: 1, + tpcwrite: 1, }, - } - ]) - }) - -}) \ No newline at end of file + }, + ]); + }); +}); diff --git a/test/api/rse/get-rse.test.ts b/test/api/rse/get-rse.test.ts index b38aeed76..d6aefa108 100644 --- a/test/api/rse/get-rse.test.ts +++ b/test/api/rse/get-rse.test.ts @@ -1,12 +1,12 @@ -import { GetRSERequest } from "@/lib/core/usecase-models/get-rse-usecase-models"; -import { GetRSEControllerParameters } from "@/lib/infrastructure/controller/get-rse-controller"; -import { RSEViewModel } from "@/lib/infrastructure/data/view-model/rse"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import CONTROLLERS from "@/lib/infrastructure/ioc/ioc-symbols-controllers"; -import { BaseController } from "@/lib/sdk/controller"; -import { NextApiResponse } from "next"; -import { createHttpMocks } from "test/fixtures/http-fixtures"; -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; +import { GetRSERequest } from '@/lib/core/usecase-models/get-rse-usecase-models'; +import { GetRSEControllerParameters } from '@/lib/infrastructure/controller/get-rse-controller'; +import { RSEViewModel } from '@/lib/infrastructure/data/view-model/rse'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers'; +import { BaseController } from '@/lib/sdk/controller'; +import { NextApiResponse } from 'next'; +import { createHttpMocks } from 'test/fixtures/http-fixtures'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; describe('GET RSE API Test', () => { beforeEach(() => { @@ -18,7 +18,7 @@ describe('GET RSE API Test', () => { volatile: false, deterministic: true, staging_area: false, - } + }; const getRSEEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/rses/DINGDONGRSE`, @@ -29,26 +29,26 @@ describe('GET RSE API Test', () => { headers: { 'Content-Type': 'application/json', }, - body: JSON.stringify(rse) - } - } + body: JSON.stringify(rse), + }, + }; MockRucioServerFactory.createMockRucioServer(true, [getRSEEndpoint]); - }) + }); afterEach(() => { fetchMock.dontMock(); - }) + }); test('it should get details for an RSE', async () => { const { req, res, session } = await createHttpMocks('/api/feature/get-rse?rseName=DINGDONGRSE', 'GET', {}); - const getRSEController = appContainer.get>(CONTROLLERS.GET_RSE) + const getRSEController = appContainer.get>(CONTROLLERS.GET_RSE); const getRSEControllerParameters: GetRSEControllerParameters = { rucioAuthToken: MockRucioServerFactory.VALID_RUCIO_TOKEN, response: res as unknown as NextApiResponse, rseName: 'DINGDONGRSE', - } - await getRSEController.execute(getRSEControllerParameters) - const data = await res._getJSONData() + }; + await getRSEController.execute(getRSEControllerParameters); + const data = await res._getJSONData(); expect(data).toEqual({ status: 'success', id: 'abcd', @@ -57,6 +57,6 @@ describe('GET RSE API Test', () => { volatile: false, deterministic: true, staging_area: false, - } as RSEViewModel) - }) -}) \ No newline at end of file + } as RSEViewModel); + }); +}); diff --git a/test/api/rse/list-all-rses.test.ts b/test/api/rse/list-all-rses.test.ts index 2da255dc9..472570614 100644 --- a/test/api/rse/list-all-rses.test.ts +++ b/test/api/rse/list-all-rses.test.ts @@ -1,23 +1,75 @@ -import { RSEType } from '@/lib/core/entity/rucio' -import { ListAllRSEsRequest } from '@/lib/core/usecase-models/list-all-rses-usecase-models' -import { ListAllRSEsControllerParameters } from '@/lib/infrastructure/controller/list-all-rses-controller' -import appContainer from '@/lib/infrastructure/ioc/container-config' -import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers' -import { BaseController } from '@/lib/sdk/controller' -import { NextApiResponse } from 'next' -import { Readable } from 'stream' -import { MockHttpStreamableResponseFactory } from 'test/fixtures/http-fixtures' -import MockRucioServerFactory, { - MockEndpoint, -} from 'test/fixtures/rucio-server' +import { RSEType } from '@/lib/core/entity/rucio'; +import { ListAllRSEsRequest } from '@/lib/core/usecase-models/list-all-rses-usecase-models'; +import { ListAllRSEsControllerParameters } from '@/lib/infrastructure/controller/list-all-rses-controller'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers'; +import { BaseController } from '@/lib/sdk/controller'; +import { NextApiResponse } from 'next'; +import { Readable } from 'stream'; +import { MockHttpStreamableResponseFactory } from 'test/fixtures/http-fixtures'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; describe('List RSEs Feature tests', () => { beforeEach(() => { - fetchMock.doMock() - const rseStream = Readable.from([ - JSON.stringify({"rse": "SWIFT", "region_code": null, "availability": 7, "created_at": "Tue, 19 Sep 2023 13:19:02 UTC", "vo": "def", "country_name": null, "availability_read": true, "updated_at": "Tue, 19 Sep 2023 13:19:02 UTC", "rse_type": "DISK", "continent": null, "availability_write": true, "deterministic": true, "time_zone": null, "availability_delete": true, "volatile": false, "ISP": null, "qos_class": null, "staging_area": false, "ASN": null, "deleted": false, "id": "59fcad356a68434cbe8c43737ccb3f83", "city": null, "longitude": null, "deleted_at": null, "latitude": null}), - JSON.stringify({"rse": "AMAZON-BOTO", "region_code": null, "availability": 7, "created_at": "Tue, 19 Sep 2023 13:19:02 UTC", "vo": "def", "country_name": null, "availability_read": true, "updated_at": "Tue, 19 Sep 2023 13:19:02 UTC", "rse_type": "DISK", "continent": null, "availability_write": true, "deterministic": true, "time_zone": null, "availability_delete": true, "volatile": false, "ISP": null, "qos_class": null, "staging_area": false, "ASN": null, "deleted": false, "id": "328c926f09ea4dc0a5ddfbe62c8e3bd5", "city": null, "longitude": null, "deleted_at": null, "latitude": null}), - ].join('\n')) + fetchMock.doMock(); + const rseStream = Readable.from( + [ + JSON.stringify({ + rse: 'SWIFT', + region_code: null, + availability: 7, + created_at: 'Tue, 19 Sep 2023 13:19:02 UTC', + vo: 'def', + country_name: null, + availability_read: true, + updated_at: 'Tue, 19 Sep 2023 13:19:02 UTC', + rse_type: 'DISK', + continent: null, + availability_write: true, + deterministic: true, + time_zone: null, + availability_delete: true, + volatile: false, + ISP: null, + qos_class: null, + staging_area: false, + ASN: null, + deleted: false, + id: '59fcad356a68434cbe8c43737ccb3f83', + city: null, + longitude: null, + deleted_at: null, + latitude: null, + }), + JSON.stringify({ + rse: 'AMAZON-BOTO', + region_code: null, + availability: 7, + created_at: 'Tue, 19 Sep 2023 13:19:02 UTC', + vo: 'def', + country_name: null, + availability_read: true, + updated_at: 'Tue, 19 Sep 2023 13:19:02 UTC', + rse_type: 'DISK', + continent: null, + availability_write: true, + deterministic: true, + time_zone: null, + availability_delete: true, + volatile: false, + ISP: null, + qos_class: null, + staging_area: false, + ASN: null, + deleted: false, + id: '328c926f09ea4dc0a5ddfbe62c8e3bd5', + city: null, + longitude: null, + deleted_at: null, + latitude: null, + }), + ].join('\n'), + ); const listAllRSEsEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/rses`, @@ -30,48 +82,46 @@ describe('List RSEs Feature tests', () => { }, body: rseStream, }, - } - - MockRucioServerFactory.createMockRucioServer(true, [listAllRSEsEndpoint]) - }) + }; + + MockRucioServerFactory.createMockRucioServer(true, [listAllRSEsEndpoint]); + }); afterEach(() => { - fetchMock.dontMock() - }) + fetchMock.dontMock(); + }); it('should list rses as a stream', async () => { - const res = MockHttpStreamableResponseFactory.getMockResponse() - const controller = appContainer.get< - BaseController - >(CONTROLLERS.LIST_ALL_RSES) + const res = MockHttpStreamableResponseFactory.getMockResponse(); + const controller = appContainer.get>(CONTROLLERS.LIST_ALL_RSES); const controllerParams: ListAllRSEsControllerParameters = { rucioAuthToken: MockRucioServerFactory.VALID_RUCIO_TOKEN, response: res as unknown as NextApiResponse, - } + }; - await controller.execute(controllerParams) + await controller.execute(controllerParams); - const receivedData: any[] = [] + const receivedData: any[] = []; const onData = (data: any) => { - receivedData.push(JSON.parse(data)) - } + receivedData.push(JSON.parse(data)); + }; const done = new Promise((resolve, reject) => { - res.on('data', onData) + res.on('data', onData); res.on('end', () => { - res.off('data', onData) - resolve() - }) + res.off('data', onData); + resolve(); + }); res.on('error', err => { - res.off('data', onData) - reject(err) - }) - }) + res.off('data', onData); + reject(err); + }); + }); - await done + await done; - expect(receivedData.length).toEqual(2) - expect(receivedData[0].id).toEqual('59fcad356a68434cbe8c43737ccb3f83') - expect(receivedData[0].rse_type).toEqual(RSEType.DISK) - }) -}) + expect(receivedData.length).toEqual(2); + expect(receivedData[0].id).toEqual('59fcad356a68434cbe8c43737ccb3f83'); + expect(receivedData[0].rse_type).toEqual(RSEType.DISK); + }); +}); diff --git a/test/api/rse/list-rses.test.ts b/test/api/rse/list-rses.test.ts index 565b2191b..4ddd95bdc 100644 --- a/test/api/rse/list-rses.test.ts +++ b/test/api/rse/list-rses.test.ts @@ -1,20 +1,18 @@ -import { RSEType } from '@/lib/core/entity/rucio' -import { ListRSEsRequest } from '@/lib/core/usecase-models/list-rses-usecase-models' -import { ListRSEsControllerParameters } from '@/lib/infrastructure/controller/list-rses-controller' -import appContainer from '@/lib/infrastructure/ioc/container-config' -import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers' -import { BaseController } from '@/lib/sdk/controller' -import { NextApiResponse } from 'next' -import { Readable } from 'stream' -import { MockHttpStreamableResponseFactory } from 'test/fixtures/http-fixtures' -import MockRucioServerFactory, { - MockEndpoint, -} from 'test/fixtures/rucio-server' +import { RSEType } from '@/lib/core/entity/rucio'; +import { ListRSEsRequest } from '@/lib/core/usecase-models/list-rses-usecase-models'; +import { ListRSEsControllerParameters } from '@/lib/infrastructure/controller/list-rses-controller'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers'; +import { BaseController } from '@/lib/sdk/controller'; +import { NextApiResponse } from 'next'; +import { Readable } from 'stream'; +import { MockHttpStreamableResponseFactory } from 'test/fixtures/http-fixtures'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; describe('List RSEs Feature tests', () => { beforeEach(() => { - fetchMock.doMock() - const rseStream = Readable.from([JSON.stringify({ rse: 'XRD1' })].join('\n')) + fetchMock.doMock(); + const rseStream = Readable.from([JSON.stringify({ rse: 'XRD1' })].join('\n')); const xrd1 = JSON.stringify({ availability_delete: true, @@ -61,7 +59,7 @@ describe('List RSEs Feature tests', () => { third_party_copy_read_protocol: 1, third_party_copy_write_protocol: 1, availability: 7, - }) + }); const listRSEsEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/rses/?expression=XRD1`, method: 'GET', @@ -73,7 +71,7 @@ describe('List RSEs Feature tests', () => { }, body: rseStream, }, - } + }; const getXRD1Endpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/rses/XRD1`, method: 'GET', @@ -85,65 +83,61 @@ describe('List RSEs Feature tests', () => { }, body: xrd1, }, - } - MockRucioServerFactory.createMockRucioServer(true, [listRSEsEndpoint, getXRD1Endpoint]) - }) + }; + MockRucioServerFactory.createMockRucioServer(true, [listRSEsEndpoint, getXRD1Endpoint]); + }); afterEach(() => { - fetchMock.dontMock() - }) + fetchMock.dontMock(); + }); it('should return with INVALID RSE EXPRESSION error if rseExpression is undefined', async () => { - const res = MockHttpStreamableResponseFactory.getMockResponse() - const controller = appContainer.get< - BaseController - >(CONTROLLERS.LIST_RSES) + const res = MockHttpStreamableResponseFactory.getMockResponse(); + const controller = appContainer.get>(CONTROLLERS.LIST_RSES); const controllerParams: ListRSEsControllerParameters = { rucioAuthToken: MockRucioServerFactory.VALID_RUCIO_TOKEN, response: res as unknown as NextApiResponse, rseExpression: '', - } + }; - await controller.execute(controllerParams) - const data = await res._getJSONData() - expect(data.status).toBe('error') - expect(data.message).toBe('RSE Expression is undefined or an empty string') - }) + await controller.execute(controllerParams); + const data = await res._getJSONData(); + expect(data.status).toBe('error'); + expect(data.message).toBe('RSE Expression is undefined or an empty string'); + }); it('should list rses as a stream', async () => { - const res = MockHttpStreamableResponseFactory.getMockResponse() + const res = MockHttpStreamableResponseFactory.getMockResponse(); - const controller = appContainer.get< - BaseController - >(CONTROLLERS.LIST_RSES) + const controller = appContainer.get>(CONTROLLERS.LIST_RSES); const controllerParams: ListRSEsControllerParameters = { rucioAuthToken: MockRucioServerFactory.VALID_RUCIO_TOKEN, response: res as unknown as NextApiResponse, rseExpression: 'XRD1', - } + }; - await controller.execute(controllerParams) + await controller.execute(controllerParams); - const receivedData: any[] = [] + const receivedData: any[] = []; const onData = (data: any) => { - receivedData.push(JSON.parse(data)) - } + receivedData.push(JSON.parse(data)); + }; const done = new Promise((resolve, reject) => { - res.on('data', onData) + res.on('data', onData); res.on('end', () => { - res.off('data', onData) - resolve() - }) + res.off('data', onData); + resolve(); + }); res.on('error', err => { - res.off('data', onData) - reject(err) - }) - }) + res.off('data', onData); + reject(err); + }); + }); - await done + await done; - expect(receivedData.length).toEqual(1) - expect(receivedData[0].id).toEqual('464cd7656db842c78261bcc2a087bbcb') - expect(receivedData[0].rse_type).toEqual(RSEType.DISK) - }) -}) + expect(receivedData.length).toEqual(1); + expect(receivedData[0].id).toEqual('464cd7656db842c78261bcc2a087bbcb'); + expect(receivedData[0].rse_type).toEqual(RSEType.DISK); + }); +}); diff --git a/test/api/rule/list-account-rse-quotas.test.ts b/test/api/rule/list-account-rse-quotas.test.ts index dc6517028..05db40695 100644 --- a/test/api/rule/list-account-rse-quotas.test.ts +++ b/test/api/rule/list-account-rse-quotas.test.ts @@ -1,20 +1,18 @@ -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; -import { Readable } from "stream"; -import { rses } from "test/fixtures/rse-fixtures"; -import { ListAccountRSEQuotasControllerParameters } from "@/lib/infrastructure/controller/list-account-rse-quotas-controller"; -import { MockHttpStreamableResponseFactory } from "test/fixtures/http-fixtures"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import { BaseController } from "@/lib/sdk/controller"; -import CONTROLLERS from "@/lib/infrastructure/ioc/ioc-symbols-controllers"; -import { ListAccountRSEQuotasRequest } from "@/lib/core/usecase-models/list-account-rse-quotas-usecase-models"; -import { NextApiResponse } from "next"; -import { DIDLong, DIDType } from "@/lib/core/entity/rucio"; -import { collectStreamedData } from "@/lib/sdk/utils"; -import { RSEAccountUsageLimitViewModel } from "@/lib/infrastructure/data/view-model/rse"; - - -describe("Create Rule: List Account RSE Quotas", () => { +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; +import { Readable } from 'stream'; +import { rses } from 'test/fixtures/rse-fixtures'; +import { ListAccountRSEQuotasControllerParameters } from '@/lib/infrastructure/controller/list-account-rse-quotas-controller'; +import { MockHttpStreamableResponseFactory } from 'test/fixtures/http-fixtures'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import { BaseController } from '@/lib/sdk/controller'; +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers'; +import { ListAccountRSEQuotasRequest } from '@/lib/core/usecase-models/list-account-rse-quotas-usecase-models'; +import { NextApiResponse } from 'next'; +import { DIDLong, DIDType } from '@/lib/core/entity/rucio'; +import { collectStreamedData } from '@/lib/sdk/utils'; +import { RSEAccountUsageLimitViewModel } from '@/lib/infrastructure/data/view-model/rse'; +describe('Create Rule: List Account RSE Quotas', () => { beforeEach(() => { fetchMock.doMock(); const accountInfoEndpoint: MockEndpoint = { @@ -27,17 +25,17 @@ describe("Create Rule: List Account RSE Quotas", () => { 'Content-Type': 'application/json', }, body: JSON.stringify({ - "status": "ACTIVE", - "deleted_at": null, - "updated_at": "2023-11-27T17:54:04", - "email": null, - "account_type": "USER", - "suspended_at": null, - "account": "root", - "created_at": "2023-11-27T17:54:04" - }) - } - } + status: 'ACTIVE', + deleted_at: null, + updated_at: '2023-11-27T17:54:04', + email: null, + account_type: 'USER', + suspended_at: null, + account: 'root', + created_at: '2023-11-27T17:54:04', + }), + }, + }; const accountLimitEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/accounts/mayank/limits`, @@ -49,22 +47,59 @@ describe("Create Rule: List Account RSE Quotas", () => { 'Content-Type': 'application/json', }, body: JSON.stringify({ - "XRD1": 200, - "XRD2": -1, - "XRD3": Infinity, - "XRD4": Infinity, - "SSH1": Infinity - }) - } - } + XRD1: 200, + XRD2: -1, + XRD3: Infinity, + XRD4: Infinity, + SSH1: Infinity, + }), + }, + }; - const rseAccountUsageStream = Readable.from([ - JSON.stringify({ "rse_id": "72fb4137ba3c460090bbd3fd8d490f8b", "rse": "XRD1", "bytes": 500, "files": 8, "bytes_limit": Infinity, "bytes_remaining": Infinity }), - JSON.stringify({ "rse_id": "d72884a3eb1747cf979af8959c978aab", "rse": "XRD2", "bytes": 100, "files": 2, "bytes_limit": 900, "bytes_remaining": 800 }), - JSON.stringify({ "rse_id": "2bb03a45a1b64b459cdc445d9844d936", "rse": "XRD3", "bytes": 400, "files": 7, "bytes_limit": 600, "bytes_remaining": 200 }), - JSON.stringify({ "rse_id": "5883a989c9c047d99d2fc1c074e40f58", "rse": "XRD4", "bytes": 300, "files": 6, "bytes_limit": 700, "bytes_remaining": 400 }), - JSON.stringify({ "rse_id": "5464fa3806324211ac5b490ce77acbfc", "rse": "SSH1", "bytes": 200, "files": 3, "bytes_limit": 800, "bytes_remaining": 600 }), - ].join('\n')) + const rseAccountUsageStream = Readable.from( + [ + JSON.stringify({ + rse_id: '72fb4137ba3c460090bbd3fd8d490f8b', + rse: 'XRD1', + bytes: 500, + files: 8, + bytes_limit: Infinity, + bytes_remaining: Infinity, + }), + JSON.stringify({ + rse_id: 'd72884a3eb1747cf979af8959c978aab', + rse: 'XRD2', + bytes: 100, + files: 2, + bytes_limit: 900, + bytes_remaining: 800, + }), + JSON.stringify({ + rse_id: '2bb03a45a1b64b459cdc445d9844d936', + rse: 'XRD3', + bytes: 400, + files: 7, + bytes_limit: 600, + bytes_remaining: 200, + }), + JSON.stringify({ + rse_id: '5883a989c9c047d99d2fc1c074e40f58', + rse: 'XRD4', + bytes: 300, + files: 6, + bytes_limit: 700, + bytes_remaining: 400, + }), + JSON.stringify({ + rse_id: '5464fa3806324211ac5b490ce77acbfc', + rse: 'SSH1', + bytes: 200, + files: 3, + bytes_limit: 800, + bytes_remaining: 600, + }), + ].join('\n'), + ); const listAccountRSEUsageEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/accounts/mayank/usage`, @@ -75,9 +110,9 @@ describe("Create Rule: List Account RSE Quotas", () => { headers: { 'Content-Type': 'application/x-json-stream', }, - body: rseAccountUsageStream - } - } + body: rseAccountUsageStream, + }, + }; const rseStream = Readable.from( [ JSON.stringify(rses['XRD1']), @@ -85,8 +120,8 @@ describe("Create Rule: List Account RSE Quotas", () => { JSON.stringify(rses['XRD3']), JSON.stringify(rses['XRD4']), JSON.stringify(rses['SSH1']), - ].join('\n') - ) + ].join('\n'), + ); const listRSEsEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/rses/`, method: 'GET', @@ -98,18 +133,25 @@ describe("Create Rule: List Account RSE Quotas", () => { }, body: rseStream, }, - } - MockRucioServerFactory.createMockRucioServer(true, [accountInfoEndpoint, accountLimitEndpoint, listAccountRSEUsageEndpoint, listRSEsEndpoint]); + }; + MockRucioServerFactory.createMockRucioServer(true, [ + accountInfoEndpoint, + accountLimitEndpoint, + listAccountRSEUsageEndpoint, + listRSEsEndpoint, + ]); }); afterEach(() => { fetchMock.dontMock(); }); - it("should return a list of account RSE quotas", async () => { - const res = MockHttpStreamableResponseFactory.getMockResponse() + it('should return a list of account RSE quotas', async () => { + const res = MockHttpStreamableResponseFactory.getMockResponse(); - const controller = appContainer.get>(CONTROLLERS.LIST_ACCOUNT_RSE_QUOTAS) + const controller = appContainer.get>( + CONTROLLERS.LIST_ACCOUNT_RSE_QUOTAS, + ); const controllerParameters: ListAccountRSEQuotasControllerParameters = { rucioAuthToken: MockRucioServerFactory.VALID_RUCIO_TOKEN, response: res as unknown as NextApiResponse, @@ -120,18 +162,17 @@ describe("Create Rule: List Account RSE Quotas", () => { name: 'container', did_type: DIDType.CONTAINER, bytes: 100, - length: 4 + length: 4, } as DIDLong, - ] - } + ], + }; - await controller.execute(controllerParameters) + await controller.execute(controllerParameters); - const recievedData: string[] = await collectStreamedData(res) - expect(recievedData.length).toEqual(5) - expect(JSON.parse(recievedData[0]).used_bytes === 500).toBeTruthy() - expect(JSON.parse(recievedData[0]).has_quota).toBeFalsy() - expect(JSON.parse(recievedData[1]).used_bytes === 0).toBeTruthy() + const recievedData: string[] = await collectStreamedData(res); + expect(recievedData.length).toEqual(5); + expect(JSON.parse(recievedData[0]).used_bytes === 500).toBeTruthy(); + expect(JSON.parse(recievedData[0]).has_quota).toBeFalsy(); + expect(JSON.parse(recievedData[1]).used_bytes === 0).toBeTruthy(); }); - -}); \ No newline at end of file +}); diff --git a/test/api/subscription/list-subscription-rule-states.test.ts b/test/api/subscription/list-subscription-rule-states.test.ts index 92911e7a3..ac7b3d9c2 100644 --- a/test/api/subscription/list-subscription-rule-states.test.ts +++ b/test/api/subscription/list-subscription-rule-states.test.ts @@ -1,18 +1,17 @@ -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; -import { Readable } from "stream"; -import { MockHttpStreamableResponseFactory } from "test/fixtures/http-fixtures"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import { BaseController } from "@/lib/sdk/controller"; -import { ListSubscriptionRuleStatesControllerParameters } from "@/lib/infrastructure/controller/list-subscription-rule-states-controller"; -import { ListSubscriptionRuleStatesRequest } from "@/lib/core/usecase-models/list-subscription-rule-states-usecase-models"; -import CONTROLLERS from "@/lib/infrastructure/ioc/ioc-symbols-controllers"; -import { NextApiResponse } from "next"; -import { generateEmptySubscriptionRuleStatesViewModel } from "@/lib/infrastructure/data/view-model/subscriptions"; - +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; +import { Readable } from 'stream'; +import { MockHttpStreamableResponseFactory } from 'test/fixtures/http-fixtures'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import { BaseController } from '@/lib/sdk/controller'; +import { ListSubscriptionRuleStatesControllerParameters } from '@/lib/infrastructure/controller/list-subscription-rule-states-controller'; +import { ListSubscriptionRuleStatesRequest } from '@/lib/core/usecase-models/list-subscription-rule-states-usecase-models'; +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers'; +import { NextApiResponse } from 'next'; +import { generateEmptySubscriptionRuleStatesViewModel } from '@/lib/infrastructure/data/view-model/subscriptions'; describe('Get Subscription Rule States', () => { beforeEach(() => { - fetchMock.doMock() + fetchMock.doMock(); const getSubscriptionRuleStatesEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/subscriptions/ddmadmin/*Functional Test/Rules/States`, method: 'GET', @@ -24,51 +23,54 @@ describe('Get Subscription Rule States', () => { }, body: Readable.from( [ - JSON.stringify(["ddmadmin", "EVNT to T0 with 1 year lifetime", "OK", 15464]), - JSON.stringify(["ddmadmin", "group.phys-gener to CERN-PROD_PHYS-GENER", "OK", 5344]), - JSON.stringify(["ddmadmin", "*Functional Test", "OK", 95918]), - JSON.stringify(["ddmadmin", "T0 DESD to T1 tape", "OK", 2382]), - JSON.stringify(["ddmadmin", "T0 DESD to T1 tape", "STUCK", 500]), - ].join('\n')) - } - } + JSON.stringify(['ddmadmin', 'EVNT to T0 with 1 year lifetime', 'OK', 15464]), + JSON.stringify(['ddmadmin', 'group.phys-gener to CERN-PROD_PHYS-GENER', 'OK', 5344]), + JSON.stringify(['ddmadmin', '*Functional Test', 'OK', 95918]), + JSON.stringify(['ddmadmin', 'T0 DESD to T1 tape', 'OK', 2382]), + JSON.stringify(['ddmadmin', 'T0 DESD to T1 tape', 'STUCK', 500]), + ].join('\n'), + ), + }, + }; MockRucioServerFactory.createMockRucioServer(true, [getSubscriptionRuleStatesEndpoint]); - }) + }); afterEach(() => { - fetchMock.dontMock() - }) + fetchMock.dontMock(); + }); test('should return a list of subscription rule states', async () => { - const res = MockHttpStreamableResponseFactory.getMockResponse() + const res = MockHttpStreamableResponseFactory.getMockResponse(); - const listSubscriptionRuleStatesController = appContainer.get>(CONTROLLERS.LIST_SUBSCRIPTION_RULE_STATES); + const listSubscriptionRuleStatesController = appContainer.get< + BaseController + >(CONTROLLERS.LIST_SUBSCRIPTION_RULE_STATES); const listSubscriptionRuleStatesControllerParams: ListSubscriptionRuleStatesControllerParameters = { account: 'ddmadmin', rucioAuthToken: MockRucioServerFactory.VALID_RUCIO_TOKEN, - response: res as unknown as NextApiResponse - } + response: res as unknown as NextApiResponse, + }; await listSubscriptionRuleStatesController.execute(listSubscriptionRuleStatesControllerParams); - const receivedData: any[] = [] + const receivedData: any[] = []; const onData = (data: any) => { - receivedData.push(JSON.parse(data)) - } + receivedData.push(JSON.parse(data)); + }; const done = new Promise((resolve, reject) => { - res.on('data', onData) + res.on('data', onData); res.on('end', () => { - res.off('data', onData) - resolve() - }) + res.off('data', onData); + resolve(); + }); res.on('error', err => { - res.off('data', onData) - reject(err) - }) - }) - - await done + res.off('data', onData); + reject(err); + }); + }); + + await done; expect(receivedData).toEqual([ { ...generateEmptySubscriptionRuleStatesViewModel(), @@ -94,8 +96,7 @@ describe('Get Subscription Rule States', () => { name: 'T0 DESD to T1 tape', state_ok: 2382, state_stuck: 500, - } - ]) - - }) -}) \ No newline at end of file + }, + ]); + }); +}); diff --git a/test/api/subscription/list-subscription.test.ts b/test/api/subscription/list-subscription.test.ts index 0ff34da99..1ddec1afe 100644 --- a/test/api/subscription/list-subscription.test.ts +++ b/test/api/subscription/list-subscription.test.ts @@ -1,22 +1,71 @@ -import { SubscriptionReplicationRule, SubscriptionState } from "@/lib/core/entity/rucio"; -import { ListSubscriptionsRequest } from "@/lib/core/usecase-models/list-subscriptions-usecase-models"; -import { ListSubscriptionsControllerParameters } from "@/lib/infrastructure/controller/list-subscriptions-controller"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import CONTROLLERS from "@/lib/infrastructure/ioc/ioc-symbols-controllers"; -import { BaseController } from "@/lib/sdk/controller"; -import { NextApiResponse } from "next"; -import { Readable } from "stream"; -import { createHttpMocks, MockHttpStreamableResponseFactory } from "test/fixtures/http-fixtures"; -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; +import { SubscriptionReplicationRule, SubscriptionState } from '@/lib/core/entity/rucio'; +import { ListSubscriptionsRequest } from '@/lib/core/usecase-models/list-subscriptions-usecase-models'; +import { ListSubscriptionsControllerParameters } from '@/lib/infrastructure/controller/list-subscriptions-controller'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers'; +import { BaseController } from '@/lib/sdk/controller'; +import { NextApiResponse } from 'next'; +import { Readable } from 'stream'; +import { createHttpMocks, MockHttpStreamableResponseFactory } from 'test/fixtures/http-fixtures'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; -describe("List Subscription Feature tests", () => { +describe('List Subscription Feature tests', () => { beforeEach(() => { fetchMock.doMock(); - const subscriptionStream = Readable.from([ - JSON.stringify({"id": "c674f72385a14dc8bb5ceba3e491da5a", "name": "wguan test weight", "filter": "{\"scope\": [\"tests\"]}", "replication_rules": "[{\"rse_expression\": \"INFN-T1_SCRATCHDISK|IN2P3-CC_SCRATCHDISK\", \"copies\": 1, \"weight\": \"stresstestweight\"}]", "policyid": 0, "state": "INACTIVE", "last_processed": "Thu, 17 Jul 2014 07:21:03 UTC", "account": "ddmadmin", "lifetime": "Tue, 01 May 2288 07:21:03 UTC", "comments": null, "retroactive": false, "expired_at": null, "created_at": "Thu, 17 Jul 2014 07:21:04 UTC", "updated_at": "Thu, 17 Jul 2014 07:21:04 UTC"}), - JSON.stringify({"id": "f8fb1e9b69e842daa0e1a29914114593", "name": "Functional test T2", "filter": "{\"project\": [\"step14\"], \"scope\": [\"tests\"], \"split_rule\": true, \"transient\": [\"None\", \"0\"]}", "replication_rules": "[{\"lifetime\": 172800, \"activity\": \"Functional Test\", \"copies\": 20, \"source_replica_expression\": \"tier=1\\\\site=CERN-PROD\", \"rse_expression\": \"(tier=2&type=DATADISK\\\\ruciotestsite=true)\\\\todecommission=true\"}]", "policyid": 0, "state": "INACTIVE", "last_processed": "Thu, 19 May 2022 11:46:11 UTC", "account": "ddmadmin", "lifetime": "Sun, 25 May 2042 15:58:21 UTC", "comments": "Functional tests from T1 to T2", "retroactive": false, "expired_at": null, "created_at": "Mon, 21 Jul 2014 12:18:39 UTC", "updated_at": "Thu, 19 May 2022 11:46:13 UTC"}), - JSON.stringify({"id": "6171d1b00b424e41a3c5c73c4cdb20b5", "name": "T0 AOD to nucleus", "filter": "{\"scope\": [\"data15_13TeV\", \"data15_5TeV\", \"data15_900GeV\", \"data15_comm\", \"data15_cos\", \"data15_hi\", \"data16_13TeV\", \"data16_14TeV\", \"data16_comm\", \"data16_cos\", \"data16_hip5TeV\", \"data16_hip8TeV\", \"data17_13TeV\", \"data17_5TeV\", \"data17_900GeV\", \"data17_comm\", \"data17_cos\", \"data17_hi\", \"data18_13TeV\", \"data18_1beam\", \"data18_1p8TeV\", \"data18_900GeV\", \"data18_calib\", \"data18_comm\", \"data18_cos\", \"data18_hi\", \"data22_13p6TeV\", \"data22_900GeV\", \"data22_comm\", \"data22_cos\", \"data22_hi\", \"data22_idcomm\"], \"datatype\": [\"AOD\"], \"transient\": [\"None\", \"0\"], \"prod_step\": [\"merge\"], \"did_type\": [\"DATASET\"], \"split_rule\": true}", "replication_rules": "[{\"copies\": 1, \"rse_expression\": \"type=DATADISK&datapolicynucleus=true\", \"activity\": \"T0 Export\", \"weight\": \"mouweight\"}]", "policyid": 3, "state": "INACTIVE", "last_processed": "Thu, 28 Jul 2022 09:11:28 UTC", "account": "ddmadmin", "lifetime": "Wed, 27 Jul 2022 09:11:49 UTC", "comments": "T0 AOD to nucleus (permanent)", "retroactive": false, "expired_at": "Thu, 28 Jul 2022 09:12:07 UTC", "created_at": "Fri, 29 May 2015 12:01:44 UTC", "updated_at": "Thu, 28 Jul 2022 09:12:07 UTC"}) - ].join('\n')) + const subscriptionStream = Readable.from( + [ + JSON.stringify({ + id: 'c674f72385a14dc8bb5ceba3e491da5a', + name: 'wguan test weight', + filter: '{"scope": ["tests"]}', + replication_rules: '[{"rse_expression": "INFN-T1_SCRATCHDISK|IN2P3-CC_SCRATCHDISK", "copies": 1, "weight": "stresstestweight"}]', + policyid: 0, + state: 'INACTIVE', + last_processed: 'Thu, 17 Jul 2014 07:21:03 UTC', + account: 'ddmadmin', + lifetime: 'Tue, 01 May 2288 07:21:03 UTC', + comments: null, + retroactive: false, + expired_at: null, + created_at: 'Thu, 17 Jul 2014 07:21:04 UTC', + updated_at: 'Thu, 17 Jul 2014 07:21:04 UTC', + }), + JSON.stringify({ + id: 'f8fb1e9b69e842daa0e1a29914114593', + name: 'Functional test T2', + filter: '{"project": ["step14"], "scope": ["tests"], "split_rule": true, "transient": ["None", "0"]}', + replication_rules: + '[{"lifetime": 172800, "activity": "Functional Test", "copies": 20, "source_replica_expression": "tier=1\\\\site=CERN-PROD", "rse_expression": "(tier=2&type=DATADISK\\\\ruciotestsite=true)\\\\todecommission=true"}]', + policyid: 0, + state: 'INACTIVE', + last_processed: 'Thu, 19 May 2022 11:46:11 UTC', + account: 'ddmadmin', + lifetime: 'Sun, 25 May 2042 15:58:21 UTC', + comments: 'Functional tests from T1 to T2', + retroactive: false, + expired_at: null, + created_at: 'Mon, 21 Jul 2014 12:18:39 UTC', + updated_at: 'Thu, 19 May 2022 11:46:13 UTC', + }), + JSON.stringify({ + id: '6171d1b00b424e41a3c5c73c4cdb20b5', + name: 'T0 AOD to nucleus', + filter: '{"scope": ["data15_13TeV", "data15_5TeV", "data15_900GeV", "data15_comm", "data15_cos", "data15_hi", "data16_13TeV", "data16_14TeV", "data16_comm", "data16_cos", "data16_hip5TeV", "data16_hip8TeV", "data17_13TeV", "data17_5TeV", "data17_900GeV", "data17_comm", "data17_cos", "data17_hi", "data18_13TeV", "data18_1beam", "data18_1p8TeV", "data18_900GeV", "data18_calib", "data18_comm", "data18_cos", "data18_hi", "data22_13p6TeV", "data22_900GeV", "data22_comm", "data22_cos", "data22_hi", "data22_idcomm"], "datatype": ["AOD"], "transient": ["None", "0"], "prod_step": ["merge"], "did_type": ["DATASET"], "split_rule": true}', + replication_rules: + '[{"copies": 1, "rse_expression": "type=DATADISK&datapolicynucleus=true", "activity": "T0 Export", "weight": "mouweight"}]', + policyid: 3, + state: 'INACTIVE', + last_processed: 'Thu, 28 Jul 2022 09:11:28 UTC', + account: 'ddmadmin', + lifetime: 'Wed, 27 Jul 2022 09:11:49 UTC', + comments: 'T0 AOD to nucleus (permanent)', + retroactive: false, + expired_at: 'Thu, 28 Jul 2022 09:12:07 UTC', + created_at: 'Fri, 29 May 2015 12:01:44 UTC', + updated_at: 'Thu, 28 Jul 2022 09:12:07 UTC', + }), + ].join('\n'), + ); const listSubscriptionsEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/subscriptions/ddmadmin`, @@ -27,9 +76,9 @@ describe("List Subscription Feature tests", () => { headers: { 'Content-Type': 'application/x-json-stream', }, - body: subscriptionStream - } - } + body: subscriptionStream, + }, + }; MockRucioServerFactory.createMockRucioServer(true, [listSubscriptionsEndpoint]); }); @@ -37,55 +86,56 @@ describe("List Subscription Feature tests", () => { afterEach(() => { fetchMock.dontMock(); }); - - it("should list subscriptions as a stream", async () => { - const res = MockHttpStreamableResponseFactory.getMockResponse() - const listSubscriptionsController = appContainer.get>(CONTROLLERS.LIST_SUBSCRIPTIONS); + it('should list subscriptions as a stream', async () => { + const res = MockHttpStreamableResponseFactory.getMockResponse(); + + const listSubscriptionsController = appContainer.get>( + CONTROLLERS.LIST_SUBSCRIPTIONS, + ); const listSubscriptionsControllerParams: ListSubscriptionsControllerParameters = { sessionAccount: 'ddmadmin', rucioAuthToken: MockRucioServerFactory.VALID_RUCIO_TOKEN, - response: res as unknown as NextApiResponse - } + response: res as unknown as NextApiResponse, + }; await listSubscriptionsController.execute(listSubscriptionsControllerParams); - const receivedData: any[] = [] + const receivedData: any[] = []; const onData = (data: any) => { - receivedData.push(JSON.parse(data)) - } + receivedData.push(JSON.parse(data)); + }; const done = new Promise((resolve, reject) => { - res.on('data', onData) + res.on('data', onData); res.on('end', () => { - res.off('data', onData) - resolve() - }) + res.off('data', onData); + resolve(); + }); res.on('error', err => { - res.off('data', onData) - reject(err) - }) - }) - - await done + res.off('data', onData); + reject(err); + }); + }); - expect(receivedData.length).toEqual(3) - expect(receivedData[0].id).toEqual('c674f72385a14dc8bb5ceba3e491da5a') - expect(receivedData[0].name).toEqual('wguan test weight') - expect(receivedData[0].filter).toEqual('{"scope": ["tests"]}') - expect(receivedData[0].policyid).toEqual(0) - expect(receivedData[0].state).toEqual(SubscriptionState.INACTIVE) - expect(receivedData[0].last_processed).toEqual('Thu, 17 Jul 2014 07:21:03 UTC') - expect(receivedData[0].account).toEqual('ddmadmin') - expect(receivedData[0].lifetime).toEqual('Tue, 01 May 2288 07:21:03 UTC') - expect(receivedData[0].comments).toEqual(undefined) + await done; - const rules: SubscriptionReplicationRule[] = JSON.parse(receivedData[0].replication_rules) - expect(rules.length).toEqual(1) - const rule = rules[0] - expect(rule.rse_expression).toEqual('INFN-T1_SCRATCHDISK|IN2P3-CC_SCRATCHDISK') - expect(rule.copies).toEqual(1) - expect(rule.weight).toEqual('stresstestweight') - }); + expect(receivedData.length).toEqual(3); + expect(receivedData[0].id).toEqual('c674f72385a14dc8bb5ceba3e491da5a'); + expect(receivedData[0].name).toEqual('wguan test weight'); + expect(receivedData[0].filter).toEqual('{"scope": ["tests"]}'); + expect(receivedData[0].policyid).toEqual(0); + expect(receivedData[0].state).toEqual(SubscriptionState.INACTIVE); + expect(receivedData[0].last_processed).toEqual('Thu, 17 Jul 2014 07:21:03 UTC'); + expect(receivedData[0].account).toEqual('ddmadmin'); + expect(receivedData[0].lifetime).toEqual('Tue, 01 May 2288 07:21:03 UTC'); + expect(receivedData[0].comments).toEqual(undefined); -}) \ No newline at end of file + const rules: SubscriptionReplicationRule[] = JSON.parse(receivedData[0].replication_rules); + expect(rules.length).toEqual(1); + const rule = rules[0]; + expect(rule.rse_expression).toEqual('INFN-T1_SCRATCHDISK|IN2P3-CC_SCRATCHDISK'); + expect(rule.copies).toEqual(1); + expect(rule.weight).toEqual('stresstestweight'); + }); +}); diff --git a/test/api/subscription/subscription.test.ts b/test/api/subscription/subscription.test.ts index 265ab9e4d..3979dc353 100644 --- a/test/api/subscription/subscription.test.ts +++ b/test/api/subscription/subscription.test.ts @@ -1,17 +1,17 @@ -import { Subscription, SubscriptionState } from "@/lib/core/entity/rucio"; -import { GetSubscriptionRequest } from "@/lib/core/usecase-models/get-subscription-usecase-models"; -import { GetSubscriptionControllerParameters } from "@/lib/infrastructure/controller/get-subscription-controller"; -import { SubscriptionViewModel } from "@/lib/infrastructure/data/view-model/subscriptions"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import CONTROLLERS from "@/lib/infrastructure/ioc/ioc-symbols-controllers"; -import { BaseController } from "@/lib/sdk/controller"; -import { NextApiResponse } from "next"; -import { createHttpMocks } from "test/fixtures/http-fixtures"; -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; +import { Subscription, SubscriptionState } from '@/lib/core/entity/rucio'; +import { GetSubscriptionRequest } from '@/lib/core/usecase-models/get-subscription-usecase-models'; +import { GetSubscriptionControllerParameters } from '@/lib/infrastructure/controller/get-subscription-controller'; +import { SubscriptionViewModel } from '@/lib/infrastructure/data/view-model/subscriptions'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers'; +import { BaseController } from '@/lib/sdk/controller'; +import { NextApiResponse } from 'next'; +import { createHttpMocks } from 'test/fixtures/http-fixtures'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; -describe("GET Subscription Feature Tests", () => { +describe('GET Subscription Feature Tests', () => { beforeEach(() => { - fetchMock.doMock() + fetchMock.doMock(); const getSubscriptionEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/subscriptions/ddmadmin/*Functional%20Test`, method: 'GET', @@ -22,40 +22,43 @@ describe("GET Subscription Feature Tests", () => { 'Content-Type': 'application/x-json-stream', }, body: JSON.stringify({ - "id": "bccaabb5877a443abd6c56f3271557df", - "name": "*Functional Test", - "filter": "{\"scope\": [\"tests\"], \"project\": [\"step14\"], \"split_rule\": true}", - "replication_rules": "[{\"activity\": \"Functional Test\", \"rse_expression\": \"tier=1&type=DATADISK\", \"source_replica_expression\": \"CERN-PROD_DATADISK\", \"copies\": \"*\", \"lifetime\": 172800, \"comments\": \"Functional tests from Tier-0 to Tier-1s\"}, {\"activity\": \"Functional Test\", \"rse_expression\": \"tier=2&type=DATADISK\", \"source_replica_expression\": \"tier=1&type=DATADISK\", \"copies\": \"*\", \"lifetime\": 172800, \"comments\": \"Functional tests from Tier-1s to Tier-2s\"}, {\"activity\": \"Functional Test\", \"rse_expression\": \"type=TEST\", \"copies\": \"*\", \"lifetime\": 172800, \"comments\": \"Functional tests to RSEs of type TEST\"}]", - "policyid": 0, - "state": "UPDATED", - "last_processed": "Tue, 18 Jul 2023 12:00:30 UTC", - "account": "ddmadmin", - "lifetime": "Sun, 25 May 2042 15:41:54 UTC", - "comments": "The Automatix daemon is configured to periodically produce small datasets for testing purposes and upload them to CERN-PROD_DATADISK. This subscription creates replication rules from Tier-0 to the Tier-1 DATADISKs, from the Tier-1s to the Tier-2 DATADISKs, and from anywhere to RSEs of type TEST. All created rules and the datasets themselves have a lifetime of 2 days.", - "retroactive": false, - "expired_at": null, - "created_at": "Wed, 21 May 2014 08:40:15 UTC", - "updated_at": "Tue, 18 Jul 2023 12:00:30 UTC" - }) - } - } + id: 'bccaabb5877a443abd6c56f3271557df', + name: '*Functional Test', + filter: '{"scope": ["tests"], "project": ["step14"], "split_rule": true}', + replication_rules: + '[{"activity": "Functional Test", "rse_expression": "tier=1&type=DATADISK", "source_replica_expression": "CERN-PROD_DATADISK", "copies": "*", "lifetime": 172800, "comments": "Functional tests from Tier-0 to Tier-1s"}, {"activity": "Functional Test", "rse_expression": "tier=2&type=DATADISK", "source_replica_expression": "tier=1&type=DATADISK", "copies": "*", "lifetime": 172800, "comments": "Functional tests from Tier-1s to Tier-2s"}, {"activity": "Functional Test", "rse_expression": "type=TEST", "copies": "*", "lifetime": 172800, "comments": "Functional tests to RSEs of type TEST"}]', + policyid: 0, + state: 'UPDATED', + last_processed: 'Tue, 18 Jul 2023 12:00:30 UTC', + account: 'ddmadmin', + lifetime: 'Sun, 25 May 2042 15:41:54 UTC', + comments: + 'The Automatix daemon is configured to periodically produce small datasets for testing purposes and upload them to CERN-PROD_DATADISK. This subscription creates replication rules from Tier-0 to the Tier-1 DATADISKs, from the Tier-1s to the Tier-2 DATADISKs, and from anywhere to RSEs of type TEST. All created rules and the datasets themselves have a lifetime of 2 days.', + retroactive: false, + expired_at: null, + created_at: 'Wed, 21 May 2014 08:40:15 UTC', + updated_at: 'Tue, 18 Jul 2023 12:00:30 UTC', + }), + }, + }; MockRucioServerFactory.createMockRucioServer(true, [getSubscriptionEndpoint]); - }); afterEach(() => { - fetchMock.dontMock() + fetchMock.dontMock(); }); - it("should get subscription", async () => { + it('should get subscription', async () => { const { req, res, session } = await createHttpMocks('/api/feature/get-subscription/ddmadmin/*Functional%20Test', 'GET', {}); - const getSubscriptionController = appContainer.get>(CONTROLLERS.GET_SUBSCRIPTION); + const getSubscriptionController = appContainer.get>( + CONTROLLERS.GET_SUBSCRIPTION, + ); const getSubscriptionControllerParams: GetSubscriptionControllerParameters = { name: '*Functional Test', sessionAccount: 'ddmadmin', rucioAuthToken: MockRucioServerFactory.VALID_RUCIO_TOKEN, - response: res as unknown as NextApiResponse - } + response: res as unknown as NextApiResponse, + }; await getSubscriptionController.execute(getSubscriptionControllerParams); expect(res._getStatusCode()).toBe(200); @@ -76,4 +79,4 @@ describe("GET Subscription Feature Tests", () => { expect(replicationRules[0].lifetime).toEqual(172800); expect(replicationRules[0].comments).toEqual('Functional tests from Tier-0 to Tier-1s'); }); -}); \ No newline at end of file +}); diff --git a/test/clean-design.test.ts b/test/clean-design.test.ts index a34ccbf06..a3e4be19f 100644 --- a/test/clean-design.test.ts +++ b/test/clean-design.test.ts @@ -1,6 +1,6 @@ -import { Container, injectable, inject, interfaces } from "inversify"; +import { Container, injectable, inject, interfaces } from 'inversify'; -describe("Test Clean Architecture Design", () => { +describe('Test Clean Architecture Design', () => { interface IUseCaseInputPort { execute(): void; } @@ -11,76 +11,71 @@ describe("Test Clean Architecture Design", () => { message: string; setMessage(message: string): void; } - + class RESTResponse implements IRESTResponse { - message: string = ""; + message: string = ''; setMessage(message: string): void { this.message = message; } } - + @injectable() class TestUseCase implements IUseCaseInputPort { - constructor(private presenter: IUseCaseOutputPort) { this.presenter = presenter; } - execute(): void{ - this.presenter.present("Hello World"); + execute(): void { + this.presenter.present('Hello World'); } } - + @injectable() class TestUseCasePresenter implements IUseCaseOutputPort { constructor(private respone: IRESTResponse) { this.respone = respone; } present(message: string): void { - this.respone.setMessage(message + Math.random()); + this.respone.setMessage(message + Math.random()); } } - + interface ITestController { handle(response: IRESTResponse): void; } - + @injectable() class TestController implements ITestController { private useCase: IUseCaseInputPort | null = null; private useCaseFactory: (response: IRESTResponse) => IUseCaseInputPort; - public constructor( - @inject('Factory') useCaseFactory: (response: IRESTResponse) => IUseCaseInputPort - ) { + public constructor(@inject('Factory') useCaseFactory: (response: IRESTResponse) => IUseCaseInputPort) { this.useCaseFactory = useCaseFactory; } handle(response: IRESTResponse): void { this.useCase = this.useCaseFactory(response); this.useCase.execute(); } - } - - it("should present unique response for each incoming request", () => { + + it('should present unique response for each incoming request', () => { const container = new Container(); - container.bind("IUseCaseInputPort").to(TestUseCase) + container.bind('IUseCaseInputPort').to(TestUseCase); // container.bind>("IUseCaseOutputPort").to(TestUseCasePresenter); - container.bind("ITestController").to(TestController); - container.bind>(`Factory`).toFactory((context: interfaces.Context) => - (response: IRESTResponse) => { + container.bind('ITestController').to(TestController); + container + .bind>(`Factory`) + .toFactory((context: interfaces.Context) => (response: IRESTResponse) => { return new TestUseCase(new TestUseCasePresenter(response)); - } - ); + }); // this is the reponse object for the first request const response1 = new RESTResponse(); // this is the response object for the second request const response2 = new RESTResponse(); - - const controller = container.get("ITestController"); + + const controller = container.get('ITestController'); controller.handle(response1); controller.handle(response2); - + expect(response1.message).not.toBe(response2.message); }); }); - diff --git a/test/component/CreateRule.test.tsx b/test/component/CreateRule.test.tsx index e614a8435..ad25e5202 100644 --- a/test/component/CreateRule.test.tsx +++ b/test/component/CreateRule.test.tsx @@ -2,77 +2,77 @@ * @jest-environment jsdom */ -import { CreateRule } from "@/component-library/Pages/Rule/CreateRule"; +import { CreateRule } from '@/component-library/Pages/Rule/CreateRule'; import { DIDSearchQuery, - TypedDIDValidationQuery, TypedDIDValidationResponse, + TypedDIDValidationQuery, + TypedDIDValidationResponse, RSESearchQuery, - CreateRulesViewModel -} from '@/lib/infrastructure/data/view-model/create-rule' -import { TCreateRuleFeatureRequestParams } from "@/pages/api/feature/create-rule"; -import { render, act, screen, cleanup, within, fireEvent } from "@testing-library/react"; -import userEvent from '@testing-library/user-event' + CreateRulesViewModel, +} from '@/lib/infrastructure/data/view-model/create-rule'; +import { TCreateRuleFeatureRequestParams } from '@/pages/api/feature/create-rule'; +import { render, act, screen, cleanup, within, fireEvent } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; -jest.mock('next/navigation') +jest.mock('next/navigation'); -let user: any // user input -let F: any // fixtures +let user: any; // user input +let F: any; // fixtures const onSubmit = (query: TCreateRuleFeatureRequestParams): Promise => { return Promise.resolve({ status: 'success', - rules: [] - }) -} + rules: [], + }); +}; const didSearch = (query: DIDSearchQuery) => { return Promise.resolve({ DIDList: [ - { DID: "First_DID", DIDType: "Dataset" as const }, - { DID: "Second_DID", DIDType: "Dataset" as const }, - { DID: "Third_DID", DIDType: "File" as const }, - { DID: query.DIDSearchString, DIDType: "Collection" as const } // just add the search string to the list - ] - }) -} + { DID: 'First_DID', DIDType: 'Dataset' as const }, + { DID: 'Second_DID', DIDType: 'Dataset' as const }, + { DID: 'Third_DID', DIDType: 'File' as const }, + { DID: query.DIDSearchString, DIDType: 'Collection' as const }, // just add the search string to the list + ], + }); +}; -const didValidation = (query: TypedDIDValidationQuery) => { +const didValidation = (query: TypedDIDValidationQuery) => { // if the DID contains the string "error", it will be added to the error list - var localErrorDIDs: TypedDIDValidationResponse = { ErrorList: [] } + var localErrorDIDs: TypedDIDValidationResponse = { ErrorList: [] }; query.DIDList.map((DID: string, index: number) => { - if (DID.includes("error")) { - localErrorDIDs.ErrorList.push({ DID: DID, ErrorCodes: [421], Message: "This DID is invalid" }) + if (DID.includes('error')) { + localErrorDIDs.ErrorList.push({ DID: DID, ErrorCodes: [421], Message: 'This DID is invalid' }); } - }) + }); // if the error list is empty, the promise will resolve, otherwise it will reject if (localErrorDIDs.ErrorList.length === 0) { - return Promise.resolve(localErrorDIDs) + return Promise.resolve(localErrorDIDs); + } else { + return Promise.reject(localErrorDIDs); } - else { - return Promise.reject(localErrorDIDs) - } -} +}; const rseSearch = (query: RSESearchQuery) => { return Promise.resolve({ RSEList: [ - { RSEName: query.RSEExpression, RSEID: "RSE0", RemainingQuota: 0, TotalQuota: 0}, - { RSEName: "RSE1", RSEID: "RSE1", RemainingQuota: 100, TotalQuota: 1000 }, - { RSEName: "RSE2", RSEID: "RSE2", RemainingQuota: 200, TotalQuota: 2000 }, - { RSEName: "RSE3", RSEID: "RSE3", RemainingQuota: 300, TotalQuota: 3000 }, - { RSEName: "RSE4", RSEID: "RSE4", RemainingQuota: 400, TotalQuota: 4000 }, - { RSEName: "RSE5", RSEID: "RSE5", RemainingQuota: 0, TotalQuota: 5000 }, - { RSEName: "RSE6", RSEID: "RSE6", RemainingQuota: 600, TotalQuota: 6000 }, - { RSEName: "RSE7", RSEID: "RSE7", RemainingQuota: 0, TotalQuota: 7000 }, - { RSEName: "RSE8", RSEID: "RSE8", RemainingQuota: 800, TotalQuota: 8000 }, - { RSEName: "RSE9", RSEID: "RSE9", RemainingQuota: 900, TotalQuota: 9000 }, - { RSEName: "RSE10", RSEID: "RSE10", RemainingQuota: 1000, TotalQuota: 10000 }, - ] - }) -} + { RSEName: query.RSEExpression, RSEID: 'RSE0', RemainingQuota: 0, TotalQuota: 0 }, + { RSEName: 'RSE1', RSEID: 'RSE1', RemainingQuota: 100, TotalQuota: 1000 }, + { RSEName: 'RSE2', RSEID: 'RSE2', RemainingQuota: 200, TotalQuota: 2000 }, + { RSEName: 'RSE3', RSEID: 'RSE3', RemainingQuota: 300, TotalQuota: 3000 }, + { RSEName: 'RSE4', RSEID: 'RSE4', RemainingQuota: 400, TotalQuota: 4000 }, + { RSEName: 'RSE5', RSEID: 'RSE5', RemainingQuota: 0, TotalQuota: 5000 }, + { RSEName: 'RSE6', RSEID: 'RSE6', RemainingQuota: 600, TotalQuota: 6000 }, + { RSEName: 'RSE7', RSEID: 'RSE7', RemainingQuota: 0, TotalQuota: 7000 }, + { RSEName: 'RSE8', RSEID: 'RSE8', RemainingQuota: 800, TotalQuota: 8000 }, + { RSEName: 'RSE9', RSEID: 'RSE9', RemainingQuota: 900, TotalQuota: 9000 }, + { RSEName: 'RSE10', RSEID: 'RSE10', RemainingQuota: 1000, TotalQuota: 10000 }, + ], + }); +}; -describe("CreateRule Test", () => { - it("test will always pass", () => { - expect(true).toBe(true) - }) -}) \ No newline at end of file +describe('CreateRule Test', () => { + it('test will always pass', () => { + expect(true).toBe(true); + }); +}); diff --git a/test/component/ListDID.test.tsx b/test/component/ListDID.test.tsx index affd5bf04..873abc1cc 100644 --- a/test/component/ListDID.test.tsx +++ b/test/component/ListDID.test.tsx @@ -2,57 +2,61 @@ * @jest-environment jsdom */ -import { render, act, screen, cleanup, fireEvent } from "@testing-library/react"; -import { ListDID as ListDIDStory } from "@/component-library/Pages/DID/ListDID"; -import { DIDMeta } from "@/lib/core/entity/rucio"; -import { fixtureDIDViewModel, fixtureDIDMetaViewModel, mockUseComDOM } from "test/fixtures/table-fixtures"; -import { DIDMetaViewModel } from "@/lib/infrastructure/data/view-model/did"; -var format = require("date-format") +import { render, act, screen, cleanup, fireEvent } from '@testing-library/react'; +import { ListDID as ListDIDStory } from '@/component-library/Pages/DID/ListDID'; +import { DIDMeta } from '@/lib/core/entity/rucio'; +import { fixtureDIDViewModel, fixtureDIDMetaViewModel, mockUseComDOM } from 'test/fixtures/table-fixtures'; +import { DIDMetaViewModel } from '@/lib/infrastructure/data/view-model/did'; +var format = require('date-format'); -describe("ListDID Story Test", () => { - it("Checks empty render of the story", async () => { - await act(async () => render( - fixtureDIDViewModel()))} - didQuery={jest.fn(x => console.log(x))} - didMetaQuery={jest.fn(x => console.log(x))} - didMetaQueryResponse={{} as DIDMetaViewModel} - /> - )) +describe('ListDID Story Test', () => { + it('Checks empty render of the story', async () => { + await act(async () => + render( + fixtureDIDViewModel()))} + didQuery={jest.fn(x => console.log(x))} + didMetaQuery={jest.fn(x => console.log(x))} + didMetaQueryResponse={{} as DIDMetaViewModel} + />, + ), + ); // check if DID Search Pattern Input exists - const searchPatternInput = screen.getByLabelText("DID Search Pattern") - expect(searchPatternInput).toHaveValue("") + const searchPatternInput = screen.getByLabelText('DID Search Pattern'); + expect(searchPatternInput).toHaveValue(''); // check if query is set to Containers and Datasets - const datasetButton= screen.getByLabelText("Dataset") - expect(datasetButton).toBeChecked() - const filesButton = screen.getByLabelText("File") - expect(filesButton).not.toBeChecked() + const datasetButton = screen.getByLabelText('Dataset'); + expect(datasetButton).toBeChecked(); + const filesButton = screen.getByLabelText('File'); + expect(filesButton).not.toBeChecked(); // Check that `No DID selected` is shown instead of the DIDMetaView, etc - const noDIDSelectedDiv = screen.getByText("No DID selected").closest("div") - expect(noDIDSelectedDiv).toHaveClass("block") - const goDIDViewLink = screen.getByText("Go To DID Page") - expect(goDIDViewLink?.parentElement).toHaveClass("hidden") + const noDIDSelectedDiv = screen.getByText('No DID selected').closest('div'); + expect(noDIDSelectedDiv).toHaveClass('block'); + const goDIDViewLink = screen.getByText('Go To DID Page'); + expect(goDIDViewLink?.parentElement).toHaveClass('hidden'); // Check that the DID Table Search is empty - const didFilterInputs = screen.getAllByPlaceholderText("Filter DID") - didFilterInputs.map((didFilterInput) => { expect(didFilterInput).toHaveValue("") }) + const didFilterInputs = screen.getAllByPlaceholderText('Filter DID'); + didFilterInputs.map(didFilterInput => { + expect(didFilterInput).toHaveValue(''); + }); // Check that we are on page 1 of 0 (I know, technically this is a bug) - const paginationNav = screen.getByRole("navigation", { name: "Table Pagination" }) - expect(paginationNav).toBeInTheDocument() - const totalPageCountSpan = screen.getByRole("generic", { name: "Total Page Count" }) - expect(totalPageCountSpan).toHaveTextContent("0") - const currentPageInput = screen.getByRole("spinbutton", { name: "Current Page Number" }) // refers to the input element (with restricted values) - expect(currentPageInput).toHaveValue(1) + const paginationNav = screen.getByRole('navigation', { name: 'Table Pagination' }); + expect(paginationNav).toBeInTheDocument(); + const totalPageCountSpan = screen.getByRole('generic', { name: 'Total Page Count' }); + expect(totalPageCountSpan).toHaveTextContent('0'); + const currentPageInput = screen.getByRole('spinbutton', { name: 'Current Page Number' }); // refers to the input element (with restricted values) + expect(currentPageInput).toHaveValue(1); // check pagination buttons - const firstPageButton = screen.getByRole("button", { name: "First Page" }) - expect(firstPageButton).toBeDisabled() - const previousPageButton = screen.getByRole("button", { name: "Previous Page" }) - expect(previousPageButton).toBeDisabled() - const nextPageButton = screen.getByRole("button", { name: "Next Page" }) - expect(nextPageButton).toBeDisabled() - const lastPageButton = screen.getByRole("button", { name: "Last Page" }) - expect(lastPageButton).toBeDisabled() - }) - it("Checks render with data and user input", async () => { + const firstPageButton = screen.getByRole('button', { name: 'First Page' }); + expect(firstPageButton).toBeDisabled(); + const previousPageButton = screen.getByRole('button', { name: 'Previous Page' }); + expect(previousPageButton).toBeDisabled(); + const nextPageButton = screen.getByRole('button', { name: 'Next Page' }); + expect(nextPageButton).toBeDisabled(); + const lastPageButton = screen.getByRole('button', { name: 'Last Page' }); + expect(lastPageButton).toBeDisabled(); + }); + it('Checks render with data and user input', async () => { /* PROBLEM: we make use of `aria-label` to identify the table rows, but the @@ -61,29 +65,31 @@ describe("ListDID Story Test", () => { SOLUTION: remove `aria-label` from the table rows, grab table rows differently. */ - const mockDIDMeta = fixtureDIDMetaViewModel() - await act(async () => render( - fixtureDIDViewModel()))} - didQuery={jest.fn(x => console.log(x))} - didMetaQuery={jest.fn(x => console.log(x))} - didMetaQueryResponse={mockDIDMeta} - /> - )) - const tableRows = screen.getAllByRole("row", {selected: false}) + const mockDIDMeta = fixtureDIDMetaViewModel(); + await act(async () => + render( + fixtureDIDViewModel()))} + didQuery={jest.fn(x => console.log(x))} + didMetaQuery={jest.fn(x => console.log(x))} + didMetaQueryResponse={mockDIDMeta} + />, + ), + ); + const tableRows = screen.getAllByRole('row', { selected: false }); // check that metaview is still invisible - const noDIDSelectedDiv = screen.getByText("No DID selected").closest("div") - expect(noDIDSelectedDiv).toHaveClass("block") + const noDIDSelectedDiv = screen.getByText('No DID selected').closest('div'); + expect(noDIDSelectedDiv).toHaveClass('block'); // click the first row - fireEvent.click(tableRows[0]) - expect(noDIDSelectedDiv).not.toHaveClass("block") - const metaDataDiv = screen.getByRole("generic", { name: "DID Metadata Quick Summary" }) - expect(metaDataDiv).toHaveClass("flex") - const goDIDViewButton = screen.getByRole("link", { name: "Go To DID Page" }) - expect(goDIDViewButton).not.toHaveClass("hidden") - const didCreationRow = screen.getByRole("row", { name: "Date of DID Creation" }) - expect(didCreationRow).toHaveTextContent(format("yyyy-MM-dd", new Date(mockDIDMeta.created_at))) - const didObsoleteRow = screen.getByRole("row", { name: "DID Obsolete" }) - expect(didObsoleteRow).toHaveTextContent(mockDIDMeta.obsolete ? "True" : "False") - }) -}) \ No newline at end of file + fireEvent.click(tableRows[0]); + expect(noDIDSelectedDiv).not.toHaveClass('block'); + const metaDataDiv = screen.getByRole('generic', { name: 'DID Metadata Quick Summary' }); + expect(metaDataDiv).toHaveClass('flex'); + const goDIDViewButton = screen.getByRole('link', { name: 'Go To DID Page' }); + expect(goDIDViewButton).not.toHaveClass('hidden'); + const didCreationRow = screen.getByRole('row', { name: 'Date of DID Creation' }); + expect(didCreationRow).toHaveTextContent(format('yyyy-MM-dd', new Date(mockDIDMeta.created_at))); + const didObsoleteRow = screen.getByRole('row', { name: 'DID Obsolete' }); + expect(didObsoleteRow).toHaveTextContent(mockDIDMeta.obsolete ? 'True' : 'False'); + }); +}); diff --git a/test/component/Login.test.tsx b/test/component/Login.test.tsx index 7ca53bb82..8fe1d5397 100644 --- a/test/component/Login.test.tsx +++ b/test/component/Login.test.tsx @@ -2,137 +2,145 @@ * @jest-environment jsdom */ -import Login from "@/app/auth/login/page"; -import { Login as LoginStory } from "@/component-library/Pages/Login/Login"; -import { render, act, screen, cleanup, fireEvent } from "@testing-library/react"; -import { LoginViewModel } from "@/lib/infrastructure/data/view-model/login" -import { useSearchParams } from "next/navigation"; -import { getSampleOIDCProviders } from "test/fixtures/oidc-provider-config"; -import { getSampleVOs } from "test/fixtures/multi-vo-fixtures"; -import { AuthViewModel } from "@/lib/infrastructure/data/auth/auth"; - -jest.mock('next/navigation') - -describe("Login Page Test", () => { +import Login from '@/app/auth/login/page'; +import { Login as LoginStory } from '@/component-library/Pages/Login/Login'; +import { render, act, screen, cleanup, fireEvent } from '@testing-library/react'; +import { LoginViewModel } from '@/lib/infrastructure/data/view-model/login'; +import { useSearchParams } from 'next/navigation'; +import { getSampleOIDCProviders } from 'test/fixtures/oidc-provider-config'; +import { getSampleVOs } from 'test/fixtures/multi-vo-fixtures'; +import { AuthViewModel } from '@/lib/infrastructure/data/auth/auth'; + +jest.mock('next/navigation'); + +describe('Login Page Test', () => { beforeEach(() => { - useSearchParams.mockReturnValue( - { - get: jest.fn(() => null) - } - ) + useSearchParams.mockReturnValue({ + get: jest.fn(() => null), + }); fetchMock.doMock(); }); afterEach(() => { - cleanup() - fetchMock.mockClear() - fetchMock.dontMock() - jest.clearAllMocks() - jest.resetAllMocks() - }) - - it("Checks initial render of Login Page", async () => { - const oidcProviders = getSampleOIDCProviders() - const voList = getSampleVOs() - fetchMock.mockIf(/login/, (req) => Promise.resolve(JSON.stringify( - { - x509Enabled: true, - oidcEnabled: true, - oidcProviders: oidcProviders, - multiVOEnabled: true, - voList: voList, - isLoggedIn: false, - status: "success", - rucioAuthHost: "https://rucio-auth-server", - } as LoginViewModel))); - - await act( async () => render()) - - // Check OIDC buttons are present but NOT rendered - voList[1].oidcProviders.map((provider) => { - const OIDCButton = screen.getByText(provider.name) - expect(OIDCButton).toBeInTheDocument() - }) - const oidcParent = screen.getByRole('generic', {name: /OIDC Login Buttons/}) - expect(oidcParent.className).not.toContain('hidden') - - // Check VO tabs are rendered - voList.map((vo) => { - const VOTab = screen.getByText(vo.name) - expect(VOTab).toBeInTheDocument() - }) - - // Check x509 button is rendered - const x509Button = screen.getByRole('button', {name: /x509/}) - expect(x509Button).toBeInTheDocument() - - // Check userpass button is rendered - const userpassButton = screen.getByRole('button', {name: /Userpass/}) - expect(userpassButton).toBeInTheDocument() - - // check userpass form is collapsed/uncollapsed on click - const loginFormParent = screen.getByRole("group", {name: "Userpass Login Fields"}) - expect(loginFormParent.className).toContain('hidden') - fireEvent.click(userpassButton) - expect(loginFormParent.className).not.toContain('hidden') - fireEvent.click(userpassButton) - expect(loginFormParent.className).toContain('hidden') - - // check only 1 account field is rendered - const accountFieldParent = screen.getByRole("group", {name: /Choose Account Name/}) - expect(accountFieldParent.className).not.toContain('hidden') - fireEvent.click(userpassButton) - expect(accountFieldParent.className).toContain('hidden') - fireEvent.click(userpassButton) - expect(accountFieldParent.className).not.toContain('hidden') - - // Check no error message is rendered - const errorElement = screen.queryByTestId('login-page-error') - expect(errorElement?.className).toBe('hidden') - - }, 1000 * 60 * 5) - - it("should not render OIDC buttons if OIDC is disabled", async () => { - fetchMock.doMock(); - fetchMock.mockIf(/login/, (req) => Promise.resolve(JSON.stringify( - { + cleanup(); + fetchMock.mockClear(); + fetchMock.dontMock(); + jest.clearAllMocks(); + jest.resetAllMocks(); + }); + + it( + 'Checks initial render of Login Page', + async () => { + const oidcProviders = getSampleOIDCProviders(); + const voList = getSampleVOs(); + fetchMock.mockIf(/login/, req => + Promise.resolve( + JSON.stringify({ x509Enabled: true, - oidcEnabled: false, - oidcProviders: getSampleOIDCProviders(), + oidcEnabled: true, + oidcProviders: oidcProviders, multiVOEnabled: true, - voList: getSampleVOs(), + voList: voList, isLoggedIn: false, - status: "error" - } as LoginViewModel))); - await act( async () => render()) + status: 'success', + rucioAuthHost: 'https://rucio-auth-server', + } as LoginViewModel), + ), + ); + + await act(async () => render()); + + // Check OIDC buttons are present but NOT rendered + voList[1].oidcProviders.map(provider => { + const OIDCButton = screen.getByText(provider.name); + expect(OIDCButton).toBeInTheDocument(); + }); + const oidcParent = screen.getByRole('generic', { name: /OIDC Login Buttons/ }); + expect(oidcParent.className).not.toContain('hidden'); + + // Check VO tabs are rendered + voList.map(vo => { + const VOTab = screen.getByText(vo.name); + expect(VOTab).toBeInTheDocument(); + }); + + // Check x509 button is rendered + const x509Button = screen.getByRole('button', { name: /x509/ }); + expect(x509Button).toBeInTheDocument(); + + // Check userpass button is rendered + const userpassButton = screen.getByRole('button', { name: /Userpass/ }); + expect(userpassButton).toBeInTheDocument(); + + // check userpass form is collapsed/uncollapsed on click + const loginFormParent = screen.getByRole('group', { name: 'Userpass Login Fields' }); + expect(loginFormParent.className).toContain('hidden'); + fireEvent.click(userpassButton); + expect(loginFormParent.className).not.toContain('hidden'); + fireEvent.click(userpassButton); + expect(loginFormParent.className).toContain('hidden'); + + // check only 1 account field is rendered + const accountFieldParent = screen.getByRole('group', { name: /Choose Account Name/ }); + expect(accountFieldParent.className).not.toContain('hidden'); + fireEvent.click(userpassButton); + expect(accountFieldParent.className).toContain('hidden'); + fireEvent.click(userpassButton); + expect(accountFieldParent.className).not.toContain('hidden'); + + // Check no error message is rendered + const errorElement = screen.queryByTestId('login-page-error'); + expect(errorElement?.className).toBe('hidden'); + }, + 1000 * 60 * 5, + ); + + it('should not render OIDC buttons if OIDC is disabled', async () => { + fetchMock.doMock(); + fetchMock.mockIf(/login/, req => + Promise.resolve( + JSON.stringify({ + x509Enabled: true, + oidcEnabled: false, + oidcProviders: getSampleOIDCProviders(), + multiVOEnabled: true, + voList: getSampleVOs(), + isLoggedIn: false, + status: 'error', + } as LoginViewModel), + ), + ); + await act(async () => render()); // Check OIDC buttons: 2 pieces and collapsed const oidcParent = screen.queryByRole('generic', { name: /OIDC Login Buttons/ }); expect(oidcParent).toBeNull(); - - }) + }); - it("should show error message if exists during initial page load", async () => { + it('should show error message if exists during initial page load', async () => { fetchMock.doMock(); - fetchMock.mockIf(/login/, (req) => Promise.resolve(JSON.stringify( - { - x509Enabled: true, - oidcEnabled: false, - oidcProviders: getSampleOIDCProviders(), - multiVOEnabled: true, - voList: getSampleVOs(), - isLoggedIn: false, - status: "error", - message: "Some Random Error Message" - } as LoginViewModel))); - await act( async () => render()) - const alert = screen.getByTestId('login-page-error') - expect(alert).toBeInTheDocument() - expect(alert.textContent).toContain("Some Random Error Message") - - }) - - it("should show error message if login fails", async () => { + fetchMock.mockIf(/login/, req => + Promise.resolve( + JSON.stringify({ + x509Enabled: true, + oidcEnabled: false, + oidcProviders: getSampleOIDCProviders(), + multiVOEnabled: true, + voList: getSampleVOs(), + isLoggedIn: false, + status: 'error', + message: 'Some Random Error Message', + } as LoginViewModel), + ), + ); + await act(async () => render()); + const alert = screen.getByTestId('login-page-error'); + expect(alert).toBeInTheDocument(); + expect(alert.textContent).toContain('Some Random Error Message'); + }); + + it('should show error message if login fails', async () => { const loginViewModel: LoginViewModel = { x509Enabled: true, oidcEnabled: false, @@ -142,43 +150,46 @@ describe("Login Page Test", () => { isLoggedIn: false, accountActive: undefined, accountsAvailable: undefined, - status: "success", - rucioAuthHost: "https://rucio-auth.cern.ch", - } + status: 'success', + rucioAuthHost: 'https://rucio-auth.cern.ch', + }; const authViewModel: AuthViewModel = { - status: "error", - message: "Invalid Credentials", - rucioAccount: "", - rucioMultiAccount: "", - rucioAuthType: "", - rucioAuthToken: "", - rucioIdentity: "", - rucioAuthTokenExpires: "", + status: 'error', + message: 'Invalid Credentials', + rucioAccount: '', + rucioMultiAccount: '', + rucioAuthType: '', + rucioAuthToken: '', + rucioIdentity: '', + rucioAuthTokenExpires: '', role: undefined, - } - - await act( async () => render( {}} - oidcSubmitHandler = {() => {}} - x509SubmitHandler = {() => { - - return Promise.resolve(authViewModel)} - } - x509SessionHandler = {(authViewModel) => {}} - />)) - expect(screen.queryByRole("dialog", {name: /Multiaccount Modal/})).not.toBeInTheDocument() - const userPassButton = screen.getByRole('button', {name: /Userpass/}) - fireEvent.click(userPassButton) - const loginButton = screen.getByRole('button', {name: /Login/}) - fireEvent.click(loginButton) - const alert = screen.getByTestId('login-page-error') - expect(alert).toBeInTheDocument() - expect(alert.textContent).toContain("Invalid Credentials") - }) - + }; + + await act(async () => + render( + {}} + oidcSubmitHandler={() => {}} + x509SubmitHandler={() => { + return Promise.resolve(authViewModel); + }} + x509SessionHandler={authViewModel => {}} + />, + ), + ); + expect(screen.queryByRole('dialog', { name: /Multiaccount Modal/ })).not.toBeInTheDocument(); + const userPassButton = screen.getByRole('button', { name: /Userpass/ }); + fireEvent.click(userPassButton); + const loginButton = screen.getByRole('button', { name: /Login/ }); + fireEvent.click(loginButton); + const alert = screen.getByTestId('login-page-error'); + expect(alert).toBeInTheDocument(); + expect(alert.textContent).toContain('Invalid Credentials'); + }); + it('test if modal will show if user has multiple accounts', async () => { const loginViewModel: LoginViewModel = { x509Enabled: true, @@ -189,35 +200,39 @@ describe("Login Page Test", () => { isLoggedIn: false, accountActive: undefined, accountsAvailable: undefined, - status: "success", - rucioAuthHost: "https://rucio-auth.cern.ch", - } + status: 'success', + rucioAuthHost: 'https://rucio-auth.cern.ch', + }; const authViewModel: AuthViewModel = { - status: "multiple_accounts", - message: "", - rucioAccount: "", - rucioMultiAccount: "account1,account2", - rucioAuthType: "", - rucioAuthToken: "", - rucioIdentity: "", - rucioAuthTokenExpires: "", + status: 'multiple_accounts', + message: '', + rucioAccount: '', + rucioMultiAccount: 'account1,account2', + rucioAuthType: '', + rucioAuthToken: '', + rucioIdentity: '', + rucioAuthTokenExpires: '', role: undefined, - } - await act( async () => render( {}} - oidcSubmitHandler = {() => {}} - x509SubmitHandler = {() => { - return Promise.resolve(authViewModel)} - } - x509SessionHandler = {(authViewModel) => {}} - />)) - - const modal = screen.getByRole("dialog", {name: /Multiaccount Modal/}) - expect(modal).toBeInTheDocument() - }) - + }; + await act(async () => + render( + {}} + oidcSubmitHandler={() => {}} + x509SubmitHandler={() => { + return Promise.resolve(authViewModel); + }} + x509SessionHandler={authViewModel => {}} + />, + ), + ); + + const modal = screen.getByRole('dialog', { name: /Multiaccount Modal/ }); + expect(modal).toBeInTheDocument(); + }); + it('should show error alert if login fails, user closes alert, and login fails again', async () => { const loginViewModel: LoginViewModel = { x509Enabled: true, @@ -228,61 +243,65 @@ describe("Login Page Test", () => { isLoggedIn: false, accountActive: undefined, accountsAvailable: undefined, - status: "success", - rucioAuthHost: "https://rucio-auth.cern.ch", - } + status: 'success', + rucioAuthHost: 'https://rucio-auth.cern.ch', + }; const authViewModel: AuthViewModel = { - status: "error", - message: "Invalid Credentials", - rucioAccount: "", - rucioMultiAccount: "", - rucioAuthType: "", - rucioAuthToken: "", - rucioIdentity: "", - rucioAuthTokenExpires: "", + status: 'error', + message: 'Invalid Credentials', + rucioAccount: '', + rucioMultiAccount: '', + rucioAuthType: '', + rucioAuthToken: '', + rucioIdentity: '', + rucioAuthTokenExpires: '', role: undefined, - } - - await act( async () => render( {}} - oidcSubmitHandler = {() => {}} - x509SubmitHandler = {() => { - const x509ErrorModel = { - ...authViewModel, - } - x509ErrorModel.message = "Oops, something went wrong" - return Promise.resolve(x509ErrorModel) - }} - x509SessionHandler = {() => {}} - />)) - + }; + + await act(async () => + render( + {}} + oidcSubmitHandler={() => {}} + x509SubmitHandler={() => { + const x509ErrorModel = { + ...authViewModel, + }; + x509ErrorModel.message = 'Oops, something went wrong'; + return Promise.resolve(x509ErrorModel); + }} + x509SessionHandler={() => {}} + />, + ), + ); + // check if Alert is displayed with message Invalid Credentials - const alertCollapsible = screen.getByTestId('login-page-error') - expect(alertCollapsible.className).not.toContain('hidden') + const alertCollapsible = screen.getByTestId('login-page-error'); + expect(alertCollapsible.className).not.toContain('hidden'); + + const alertCloseButton = screen.getByRole('button', { name: /Close/ }); - const alertCloseButton = screen.getByRole('button', {name: /Close/}) - // close the alert - await act( async () => fireEvent.click(alertCloseButton)) + await act(async () => fireEvent.click(alertCloseButton)); // check if Alert is not displayed - expect(alertCollapsible.className).toContain('hidden') + expect(alertCollapsible.className).toContain('hidden'); // Login again - const x509LoginButton = screen.getByRole('button', {name: /x509/}) - await act( async () => fireEvent.click(x509LoginButton)) + const x509LoginButton = screen.getByRole('button', { name: /x509/ }); + await act(async () => fireEvent.click(x509LoginButton)); // check if Alert is displayed with message Oops, something went wrong - expect(alertCollapsible.className).not.toContain('hidden') - expect(alertCollapsible.textContent).toContain('Oops, something went wrong') + expect(alertCollapsible.className).not.toContain('hidden'); + expect(alertCollapsible.textContent).toContain('Oops, something went wrong'); // close the alert again - await act( async () => fireEvent.click(alertCloseButton)) + await act(async () => fireEvent.click(alertCloseButton)); // check if Alert is not displayed - expect(alertCollapsible.className).toContain('hidden') - }) -}) \ No newline at end of file + expect(alertCollapsible.className).toContain('hidden'); + }); +}); diff --git a/test/component/LoginX509.test.tsx b/test/component/LoginX509.test.tsx index 07a2e564f..b18782359 100644 --- a/test/component/LoginX509.test.tsx +++ b/test/component/LoginX509.test.tsx @@ -1,35 +1,31 @@ -import { useRouter, useSearchParams } from "next/navigation"; -import Login from "@/app/auth/login/page"; -import { act, render, screen, cleanup, fireEvent } from "@testing-library/react"; -import { LoginViewModel } from "@/lib/infrastructure/data/view-model/login"; -import { getSampleVOs } from "test/fixtures/multi-vo-fixtures"; -import { getSampleOIDCProviders } from "test/fixtures/oidc-provider-config"; -import { AuthViewModel } from "@/lib/infrastructure/data/auth/auth"; -jest.mock('next/navigation') +import { useRouter, useSearchParams } from 'next/navigation'; +import Login from '@/app/auth/login/page'; +import { act, render, screen, cleanup, fireEvent } from '@testing-library/react'; +import { LoginViewModel } from '@/lib/infrastructure/data/view-model/login'; +import { getSampleVOs } from 'test/fixtures/multi-vo-fixtures'; +import { getSampleOIDCProviders } from 'test/fixtures/oidc-provider-config'; +import { AuthViewModel } from '@/lib/infrastructure/data/auth/auth'; +jest.mock('next/navigation'); describe('Login Component Tests for x509 Login workflow', () => { beforeEach(() => { - useSearchParams.mockReturnValue( - { - get: jest.fn(() => null) - } - ) - useRouter.mockReturnValue( - { - push: jest.fn() - } - ) + useSearchParams.mockReturnValue({ + get: jest.fn(() => null), + }); + useRouter.mockReturnValue({ + push: jest.fn(), + }); fetchMock.doMock(); }); afterEach(() => { - fetchMock.mockClear() - fetchMock.dontMock() - jest.clearAllMocks() - jest.resetAllMocks() - cleanup() - }) + fetchMock.mockClear(); + fetchMock.dontMock(); + jest.clearAllMocks(); + jest.resetAllMocks(); + cleanup(); + }); it('should send well formed request to RUCIO_AUTH_HOST/auth/x509 endpoint and handle successful response', async () => { - fetchMock.mockIf(/.*/, (req) => { + fetchMock.mockIf(/.*/, req => { if (req.url === '/api/auth/login' && req.method === 'POST') { return Promise.resolve({ body: JSON.stringify({ @@ -39,45 +35,41 @@ describe('Login Component Tests for x509 Login workflow', () => { multiVOEnabled: true, voList: getSampleVOs(), isLoggedIn: false, - status: "success", - rucioAuthHost: "https://rucio-auth-server", - } as LoginViewModel) + status: 'success', + rucioAuthHost: 'https://rucio-auth-server', + } as LoginViewModel), }); } else if (req.url === 'https://rucio-auth-server/auth/x509' && req.method === 'GET') { - expect(req.headers.get('X-Rucio-VO')).toBe('atl') - expect(req.headers.get('X-Rucio-AppID')).toBe('rucio-webui') - expect(req.headers.get('X-Rucio-Allow-Return-Multiple-Accounts')).toBe('true') - return Promise.resolve( - { - status: 200, - headers: { - 'Content-Type': 'application/json', - 'X-Rucio-Auth-Token': 'rucio-asdnjkdf', - 'X-Rucio-Auth-Token-Expires': '2021-09-01T00:00:00Z', - 'X-Rucio-Auth-Account': 'root', - }, - body: JSON.stringify({ - rucioAuthToken: 'rucio-asdnjkdf' - }) - }) + expect(req.headers.get('X-Rucio-VO')).toBe('atl'); + expect(req.headers.get('X-Rucio-AppID')).toBe('rucio-webui'); + expect(req.headers.get('X-Rucio-Allow-Return-Multiple-Accounts')).toBe('true'); + return Promise.resolve({ + status: 200, + headers: { + 'Content-Type': 'application/json', + 'X-Rucio-Auth-Token': 'rucio-asdnjkdf', + 'X-Rucio-Auth-Token-Expires': '2021-09-01T00:00:00Z', + 'X-Rucio-Auth-Account': 'root', + }, + body: JSON.stringify({ + rucioAuthToken: 'rucio-asdnjkdf', + }), + }); } else { - return Promise.resolve( - JSON.stringify({}) - ) + return Promise.resolve(JSON.stringify({})); } - }) + }); await act(() => { - render() - }) + render(); + }); - const x509Button = screen.getByRole('button', { name: /x509/ }) - expect(x509Button).toBeInTheDocument() + const x509Button = screen.getByRole('button', { name: /x509/ }); + expect(x509Button).toBeInTheDocument(); - await act(() => fireEvent.click(x509Button)) - expect(fetchMock).toBeCalledTimes(2) - - }) + await act(() => fireEvent.click(x509Button)); + expect(fetchMock).toBeCalledTimes(2); + }); // it('should handle HTTP 401 Unauthorized response', async () => { // fetchMock.mockIf(/.*/, async (req) => { @@ -102,7 +94,7 @@ describe('Login Component Tests for x509 Login workflow', () => { // { // status: 401, // headers: { - + // }, // body: JSON.stringify({ // ExceptionClass: 'CannotAuthenticate', @@ -122,7 +114,7 @@ describe('Login Component Tests for x509 Login workflow', () => { // await act(() => { // render() // }) - + // const x509Button = screen.getByRole('button', { name: /x509/ }) // expect(x509Button).toBeInTheDocument() @@ -135,7 +127,7 @@ describe('Login Component Tests for x509 Login workflow', () => { // }) it('should handle HTTP 206 multiple accounts response', async () => { - fetchMock.mockIf(/.*/, async (req) => { + fetchMock.mockIf(/.*/, async req => { if (req.url === '/api/auth/login' && req.method === 'POST') { return Promise.resolve({ body: JSON.stringify({ @@ -145,42 +137,42 @@ describe('Login Component Tests for x509 Login workflow', () => { multiVOEnabled: true, voList: getSampleVOs(), isLoggedIn: false, - status: "success", - rucioAuthHost: "https://rucio-auth-server", - } as LoginViewModel) + status: 'success', + rucioAuthHost: 'https://rucio-auth-server', + } as LoginViewModel), }); } else if (req.url === 'https://rucio-auth-server/auth/x509' && req.method === 'GET') { - expect(req.headers.get('X-Rucio-VO')).toBe('atl') - expect(req.headers.get('X-Rucio-AppID')).toBe('rucio-webui') - expect(req.headers.get('X-Rucio-Allow-Return-Multiple-Accounts')).toBe('true') - return Promise.resolve( - { - status: 206, - headers: { - 'X-Rucio-Auth-Accounts': 'ddmlab,root,test' - }, - }) + expect(req.headers.get('X-Rucio-VO')).toBe('atl'); + expect(req.headers.get('X-Rucio-AppID')).toBe('rucio-webui'); + expect(req.headers.get('X-Rucio-Allow-Return-Multiple-Accounts')).toBe('true'); + return Promise.resolve({ + status: 206, + headers: { + 'X-Rucio-Auth-Accounts': 'ddmlab,root,test', + }, + }); } else if (req.url === '/api/auth/x509' && req.method === 'POST') { - const body: AuthViewModel = await req.json() - expect(body).toHaveProperty('rucioAuthToken') - expect(body.rucioAuthToken).toBe('rucio-asdnjkdf') + const body: AuthViewModel = await req.json(); + expect(body).toHaveProperty('rucioAuthToken'); + expect(body.rucioAuthToken).toBe('rucio-asdnjkdf'); return Promise.resolve({ status: 200, - }) + }); } - }) + }); await act(() => { - render() - }) - - const x509Button = screen.getByRole('button', { name: /x509/ }) - expect(x509Button).toBeInTheDocument() + render(); + }); + + const x509Button = screen.getByRole('button', { name: /x509/ }); + expect(x509Button).toBeInTheDocument(); - await act(() => { fireEvent.click(x509Button) }) - expect(fetchMock).toBeCalledTimes(2) + await act(() => { + fireEvent.click(x509Button); + }); + expect(fetchMock).toBeCalledTimes(2); // TODO check if modal is displayed and if it contains the correct accounts (ddmlab,root,test) - - }) -}) \ No newline at end of file + }); +}); diff --git a/test/component/PageRule.test.tsx b/test/component/PageRule.test.tsx index 031b34241..6ebf43eb2 100644 --- a/test/component/PageRule.test.tsx +++ b/test/component/PageRule.test.tsx @@ -2,61 +2,58 @@ * @jest-environment jsdom */ -import { render, act, screen, cleanup, fireEvent, getByRole } from "@testing-library/react"; -import userEvent from "@testing-library/user-event"; -import { PageRule as PageRuleStory } from "@/component-library/Pages/Rule/PageRule"; -import { fixtureRulePageLockEntryViewModel, fixtureRuleMetaViewModel, mockUseComDOM } from "test/fixtures/table-fixtures"; -var format = require("date-format") +import { render, act, screen, cleanup, fireEvent, getByRole } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { PageRule as PageRuleStory } from '@/component-library/Pages/Rule/PageRule'; +import { fixtureRulePageLockEntryViewModel, fixtureRuleMetaViewModel, mockUseComDOM } from 'test/fixtures/table-fixtures'; +var format = require('date-format'); -const ruleMeta = fixtureRuleMetaViewModel() +const ruleMeta = fixtureRuleMetaViewModel(); -describe("PageRule Story Test", () => { - it("Check Subpage Movement", async () => { - await act(async () => render( - fixtureRulePageLockEntryViewModel()))} - ruleBoostFunc={() => {}} - ruleBoostShow={false} - /> - )) - const user = userEvent.setup() - const selectedTabExpect = () => expect(screen.getByRole("tab", { selected: true })) +describe('PageRule Story Test', () => { + it('Check Subpage Movement', async () => { + await act(async () => + render( + fixtureRulePageLockEntryViewModel()))} + ruleBoostFunc={() => {}} + ruleBoostShow={false} + />, + ), + ); + const user = userEvent.setup(); + const selectedTabExpect = () => expect(screen.getByRole('tab', { selected: true })); // check if the metadata tab is active - selectedTabExpect().toHaveTextContent("Metadata") + selectedTabExpect().toHaveTextContent('Metadata'); // assert metadata is visible - expect(screen.queryByRole("tabpanel", { name: "Metadata" })).toBeVisible() + expect(screen.queryByRole('tabpanel', { name: 'Metadata' })).toBeVisible(); // click on locks tab - await user.click(screen.getByRole("tab", { name: "Locks"})) - selectedTabExpect().toHaveTextContent("Locks") - expect(screen.queryByRole("tabpanel", { name: "Locks" })).toBeVisible() + await user.click(screen.getByRole('tab', { name: 'Locks' })); + selectedTabExpect().toHaveTextContent('Locks'); + expect(screen.queryByRole('tabpanel', { name: 'Locks' })).toBeVisible(); // assert header is properly done - expect( - screen.getByRole("heading", { name: /For rule/}) - ).toHaveTextContent( - `${ruleMeta.scope}:${ruleMeta.name}` - ) + expect(screen.getByRole('heading', { name: /For rule/ })).toHaveTextContent(`${ruleMeta.scope}:${ruleMeta.name}`); - - await user.click(screen.getByRole("tab", { name: "Locks"})) + await user.click(screen.getByRole('tab', { name: 'Locks' })); // arrow right to focus the `metadata` tab (test cycling!) - await user.keyboard("{arrowright}") - selectedTabExpect().toHaveTextContent("Metadata") + await user.keyboard('{arrowright}'); + selectedTabExpect().toHaveTextContent('Metadata'); // arrow right to focus `locks` - await user.keyboard("{arrowright}") - selectedTabExpect().toHaveTextContent("Locks") + await user.keyboard('{arrowright}'); + selectedTabExpect().toHaveTextContent('Locks'); // tab again to focus `filter DID` input - await user.tab() - expect(screen.getByPlaceholderText(/Filter DID/)).toHaveFocus() + await user.tab(); + expect(screen.getByPlaceholderText(/Filter DID/)).toHaveFocus(); // NB: we cant test further tabbing, because the testing library doesnt // support responsive design: this means that the next tab will lead to // the `Magnifying Glass` button which would be hidden otherwise. // back to `locks` tab - await user.tab({shift: true}) + await user.tab({ shift: true }); // arrow left to focus the `metadata` tab - await user.keyboard("{arrowleft}") - selectedTabExpect().toHaveTextContent("Metadata") - }) -}) \ No newline at end of file + await user.keyboard('{arrowleft}'); + selectedTabExpect().toHaveTextContent('Metadata'); + }); +}); diff --git a/test/component/jest.component.setup.ts b/test/component/jest.component.setup.ts index 73c927952..d11225348 100644 --- a/test/component/jest.component.setup.ts +++ b/test/component/jest.component.setup.ts @@ -1,18 +1,17 @@ -import '@testing-library/jest-dom/extend-expect' -import "reflect-metadata" -import fetchMock from 'jest-fetch-mock' -import "@inrupt/jest-jsdom-polyfills" -fetchMock.enableMocks() +import '@testing-library/jest-dom/extend-expect'; +import 'reflect-metadata'; +import fetchMock from 'jest-fetch-mock'; +import '@inrupt/jest-jsdom-polyfills'; +fetchMock.enableMocks(); -import { loadEnvConfig } from '@next/env' +import { loadEnvConfig } from '@next/env'; const noop = () => {}; Object.defineProperty(window, 'scrollTo', { value: noop, writable: true }); const setupTests = async () => { - const projectDir = process.cwd() - loadEnvConfig(projectDir) - -} + const projectDir = process.cwd(); + loadEnvConfig(projectDir); +}; -export default setupTests \ No newline at end of file +export default setupTests; diff --git a/test/fixtures/http-fixtures.ts b/test/fixtures/http-fixtures.ts index aca1df653..fb4fc4332 100644 --- a/test/fixtures/http-fixtures.ts +++ b/test/fixtures/http-fixtures.ts @@ -1,8 +1,8 @@ -import { getIronSession } from "iron-session"; -import { createMocks, createResponse, MockResponse } from "node-mocks-http"; -import { EventEmitter } from "stream"; -import { Response } from "express"; -import MockRucioServerFactory from "./rucio-server"; +import { getIronSession } from 'iron-session'; +import { createMocks, createResponse, MockResponse } from 'node-mocks-http'; +import { EventEmitter } from 'stream'; +import { Response } from 'express'; +import MockRucioServerFactory from './rucio-server'; /** * Creates mock HTTP request and response objects for testing. This is used to mock the requests to NextJS endpoints. @@ -12,10 +12,10 @@ import MockRucioServerFactory from "./rucio-server"; * @param body The request body. * @returns An object containing the mock request, response, and session objects. */ -export async function createHttpMocks(url?: string, method?: 'GET' | 'POST', body: any = {}){ +export async function createHttpMocks(url?: string, method?: 'GET' | 'POST', body: any = {}) { const { req, res } = createMocks({ - url: url? url: 'http://testhost:3000/', - method: method? method: 'GET', + url: url ? url : 'http://testhost:3000/', + method: method ? method : 'GET', body: body, }); const session = await getIronSession(req, res, { @@ -24,11 +24,10 @@ export async function createHttpMocks(url?: string, method?: 'GET' | 'POST', bod cookieOptions: { secure: false, }, - }) - return { req, res, session } + }); + return { req, res, session }; } - /** * A factory for creating mock HTTP streamable responses. * This is used to capture the responses that will be received by the UI. @@ -43,13 +42,13 @@ export class MockHttpStreamableResponseFactory { static getMockResponse(): MockResponse { const response = createResponse({ eventEmitter: EventEmitter, - }) + }); const oldWrite = response.write; - response.write = function(data: any, encoding: any, callback?: (error?: Error | null) => void) { - oldWrite.call(response, data, encoding, callback) - response.emit('data', data) + response.write = function (data: any, encoding: any, callback?: (error?: Error | null) => void) { + oldWrite.call(response, data, encoding, callback); + response.emit('data', data); return true; - } - return response + }; + return response; } -} \ No newline at end of file +} diff --git a/test/fixtures/multi-vo-fixtures.ts b/test/fixtures/multi-vo-fixtures.ts index 3548a595a..013c5fc6c 100644 --- a/test/fixtures/multi-vo-fixtures.ts +++ b/test/fixtures/multi-vo-fixtures.ts @@ -1,34 +1,33 @@ -import { VO } from "@/lib/core/entity/auth-models"; -import { getSampleOIDCProviders } from "./oidc-provider-config"; +import { VO } from '@/lib/core/entity/auth-models'; +import { getSampleOIDCProviders } from './oidc-provider-config'; export const getSampleVOs = (): VO[] => { const vos: VO[] = []; const atlas: VO = { - name: "ATLAS", - shortName: "atl", - logoUrl: "https://atlas.ch/logo.png", + name: 'ATLAS', + shortName: 'atl', + logoUrl: 'https://atlas.ch/logo.png', oidcEnabled: true, oidcProviders: [getSampleOIDCProviders()[0]], }; const cms: VO = { - name: "CMS", - shortName: "cms", - logoUrl: "https://cms.ch/logo.png", + name: 'CMS', + shortName: 'cms', + logoUrl: 'https://cms.ch/logo.png', oidcEnabled: true, oidcProviders: [getSampleOIDCProviders()[0]], }; vos.push(atlas); vos.push(cms); return vos; -} +}; export const getDefaultVO = (): VO => { - return { - name: "Default", - shortName: "def", - logoUrl: "https://atlas.ch/logo.png", + name: 'Default', + shortName: 'def', + logoUrl: 'https://atlas.ch/logo.png', oidcEnabled: false, oidcProviders: [], }; -} \ No newline at end of file +}; diff --git a/test/fixtures/oidc-provider-config.ts b/test/fixtures/oidc-provider-config.ts index 5279a452b..50f0cdd2c 100644 --- a/test/fixtures/oidc-provider-config.ts +++ b/test/fixtures/oidc-provider-config.ts @@ -1,7 +1,7 @@ -import { OIDCProvider } from "@/lib/core/entity/auth-models" +import { OIDCProvider } from '@/lib/core/entity/auth-models'; export const getSampleOIDCProviders = (): OIDCProvider[] => { - const oidcProviders: OIDCProvider[] = [] + const oidcProviders: OIDCProvider[] = []; const cern: OIDCProvider = { name: 'cern', url: 'https://cern.ch', @@ -12,7 +12,7 @@ export const getSampleOIDCProviders = (): OIDCProvider[] => { authorizationUrl: 'https://cern.ch/auth', tokenUrl: 'https://cern.ch/token', redirectUrl: 'https://cern.ch/redirect', - } + }; const testProvider: OIDCProvider = { name: 'test-provider', url: 'https://test-provider.ch', @@ -23,73 +23,64 @@ export const getSampleOIDCProviders = (): OIDCProvider[] => { authorizationUrl: 'https://test-provider.ch/auth', tokenUrl: 'https://test-provider.ch/token', redirectUrl: 'https://test-provider.ch/redirect', - } - oidcProviders.push(cern) - oidcProviders.push(testProvider) - return oidcProviders -} + }; + oidcProviders.push(cern); + oidcProviders.push(testProvider); + return oidcProviders; +}; export const createOIDCProviders = () => { - process.env['OIDC_ENABLED'] = 'true' - process.env['OIDC_PROVIDERS'] = 'cern, test-provider' - process.env['OIDC_PROVIDER_CERN_URL'] = 'https://cern.ch' - process.env['OIDC_PROVIDER_CERN_ICON_URL'] = 'https://cern.ch/icon.png' - process.env['OIDC_PROVIDER_CERN_CLIENT_ID'] = 'client-id' - process.env['OIDC_PROVIDER_CERN_CLIENT_SECRET'] = 'client-secret' - process.env['OIDC_PROVIDER_CERN_SCOPES'] = 'scope1,scope2' - process.env['OIDC_PROVIDER_CERN_AUTHORIZATION_URL'] = 'https://cern.ch/auth' - process.env['OIDC_PROVIDER_CERN_TOKEN_URL'] = 'https://cern.ch/token' - process.env['OIDC_PROVIDER_CERN_USERINFO_URL'] = 'https://cern.ch/userinfo' - process.env['OIDC_PROVIDER_CERN_REDIRECT_URL'] = 'https://cern.ch/redirect' - process.env['OIDC_PROVIDER_CERN_REFRESH_TOKEN_URL'] = - 'https://cern.ch/userinfo' - process.env['OIDC_PROVIDER_CERN_LOGOUT_URL'] = 'https://cern.ch/logout' + process.env['OIDC_ENABLED'] = 'true'; + process.env['OIDC_PROVIDERS'] = 'cern, test-provider'; + process.env['OIDC_PROVIDER_CERN_URL'] = 'https://cern.ch'; + process.env['OIDC_PROVIDER_CERN_ICON_URL'] = 'https://cern.ch/icon.png'; + process.env['OIDC_PROVIDER_CERN_CLIENT_ID'] = 'client-id'; + process.env['OIDC_PROVIDER_CERN_CLIENT_SECRET'] = 'client-secret'; + process.env['OIDC_PROVIDER_CERN_SCOPES'] = 'scope1,scope2'; + process.env['OIDC_PROVIDER_CERN_AUTHORIZATION_URL'] = 'https://cern.ch/auth'; + process.env['OIDC_PROVIDER_CERN_TOKEN_URL'] = 'https://cern.ch/token'; + process.env['OIDC_PROVIDER_CERN_USERINFO_URL'] = 'https://cern.ch/userinfo'; + process.env['OIDC_PROVIDER_CERN_REDIRECT_URL'] = 'https://cern.ch/redirect'; + process.env['OIDC_PROVIDER_CERN_REFRESH_TOKEN_URL'] = 'https://cern.ch/userinfo'; + process.env['OIDC_PROVIDER_CERN_LOGOUT_URL'] = 'https://cern.ch/logout'; - process.env['OIDC_PROVIDER_TEST-PROVIDER_URL'] = 'https://test-provider.ch' - process.env['OIDC_PROVIDER_TEST-PROVIDER_ICON_URL'] = - 'https://test-provider.ch/icon.png' - process.env['OIDC_PROVIDER_TEST-PROVIDER_CLIENT_ID'] = 'client-id' - process.env['OIDC_PROVIDER_TEST-PROVIDER_CLIENT_SECRET'] = 'client-secret' - process.env['OIDC_PROVIDER_TEST-PROVIDER_SCOPES'] = 'scope1,scope2' - process.env['OIDC_PROVIDER_TEST-PROVIDER_AUTHORIZATION_URL'] = - 'https://test-provider.ch/auth' - process.env['OIDC_PROVIDER_TEST-PROVIDER_TOKEN_URL'] = - 'https://test-provider.ch/token' - process.env['OIDC_PROVIDER_TEST-PROVIDER_USERINFO_URL'] = - 'https://test-provider.ch/userinfo' - process.env['OIDC_PROVIDER_TEST-PROVIDER_REDIRECT_URL'] = - 'https://test-provider.ch/redirect' - process.env['OIDC_PROVIDER_TEST-PROVIDER_REFRESH_TOKEN_URL'] = - 'https://test-provider.ch/userinfo' - process.env['OIDC_PROVIDER_TEST-PROVIDER_LOGOUT_URL'] = - 'https://test-provider.ch/logout' -} + process.env['OIDC_PROVIDER_TEST-PROVIDER_URL'] = 'https://test-provider.ch'; + process.env['OIDC_PROVIDER_TEST-PROVIDER_ICON_URL'] = 'https://test-provider.ch/icon.png'; + process.env['OIDC_PROVIDER_TEST-PROVIDER_CLIENT_ID'] = 'client-id'; + process.env['OIDC_PROVIDER_TEST-PROVIDER_CLIENT_SECRET'] = 'client-secret'; + process.env['OIDC_PROVIDER_TEST-PROVIDER_SCOPES'] = 'scope1,scope2'; + process.env['OIDC_PROVIDER_TEST-PROVIDER_AUTHORIZATION_URL'] = 'https://test-provider.ch/auth'; + process.env['OIDC_PROVIDER_TEST-PROVIDER_TOKEN_URL'] = 'https://test-provider.ch/token'; + process.env['OIDC_PROVIDER_TEST-PROVIDER_USERINFO_URL'] = 'https://test-provider.ch/userinfo'; + process.env['OIDC_PROVIDER_TEST-PROVIDER_REDIRECT_URL'] = 'https://test-provider.ch/redirect'; + process.env['OIDC_PROVIDER_TEST-PROVIDER_REFRESH_TOKEN_URL'] = 'https://test-provider.ch/userinfo'; + process.env['OIDC_PROVIDER_TEST-PROVIDER_LOGOUT_URL'] = 'https://test-provider.ch/logout'; +}; export const deleteOIDCProviders = () => { - delete process.env['OIDC_ENABLED'] - delete process.env['OIDC_PROVIDERS'] - delete process.env['OIDC_PROVIDER_CERN_URL'] - delete process.env['OIDC_PROVIDER_CERN_ICON_URL'] - delete process.env['OIDC_PROVIDER_CERN_CLIENT_ID'] - delete process.env['OIDC_PROVIDER_CERN_CLIENT_SECRET'] - delete process.env['OIDC_PROVIDER_CERN_SCOPES'] - delete process.env['OIDC_PROVIDER_CERN_AUTHORIZATION_URL'] - delete process.env['OIDC_PROVIDER_CERN_TOKEN_URL'] - delete process.env['OIDC_PROVIDER_CERN_USERINFO_URL'] - delete process.env['OIDC_PROVIDER_CERN_REDIRECT_URL'] - delete process.env['OIDC_PROVIDER_CERN_REFRESH_TOKEN_URL'] - delete process.env['OIDC_PROVIDER_CERN_LOGOUT_URL'] + delete process.env['OIDC_ENABLED']; + delete process.env['OIDC_PROVIDERS']; + delete process.env['OIDC_PROVIDER_CERN_URL']; + delete process.env['OIDC_PROVIDER_CERN_ICON_URL']; + delete process.env['OIDC_PROVIDER_CERN_CLIENT_ID']; + delete process.env['OIDC_PROVIDER_CERN_CLIENT_SECRET']; + delete process.env['OIDC_PROVIDER_CERN_SCOPES']; + delete process.env['OIDC_PROVIDER_CERN_AUTHORIZATION_URL']; + delete process.env['OIDC_PROVIDER_CERN_TOKEN_URL']; + delete process.env['OIDC_PROVIDER_CERN_USERINFO_URL']; + delete process.env['OIDC_PROVIDER_CERN_REDIRECT_URL']; + delete process.env['OIDC_PROVIDER_CERN_REFRESH_TOKEN_URL']; + delete process.env['OIDC_PROVIDER_CERN_LOGOUT_URL']; - delete process.env['OIDC_PROVIDER_TEST-PROVIDER_URL'] - delete process.env['OIDC_PROVIDER_TEST-PROVIDER_ICON_URL'] - delete process.env['OIDC_PROVIDER_TEST-PROVIDER_CLIENT_ID'] - delete process.env['OIDC_PROVIDER_TEST-PROVIDER_CLIENT_SECRET'] - delete process.env['OIDC_PROVIDER_TEST-PROVIDER_SCOPES'] - delete process.env['OIDC_PROVIDER_TEST-PROVIDER_AUTHORIZATION_URL'] - delete process.env['OIDC_PROVIDER_TEST-PROVIDER_TOKEN_URL'] - delete process.env['OIDC_PROVIDER_TEST-PROVIDER_USERINFO_URL'] - delete process.env['OIDC_PROVIDER_TEST-PROVIDER_REDIRECT_URL'] - delete process.env['OIDC_PROVIDER_TEST-PROVIDER_REFRESH_TOKEN_URL'] - delete process.env['OIDC_PROVIDER_TEST-PROVIDER_LOGOUT_URL'] - -} \ No newline at end of file + delete process.env['OIDC_PROVIDER_TEST-PROVIDER_URL']; + delete process.env['OIDC_PROVIDER_TEST-PROVIDER_ICON_URL']; + delete process.env['OIDC_PROVIDER_TEST-PROVIDER_CLIENT_ID']; + delete process.env['OIDC_PROVIDER_TEST-PROVIDER_CLIENT_SECRET']; + delete process.env['OIDC_PROVIDER_TEST-PROVIDER_SCOPES']; + delete process.env['OIDC_PROVIDER_TEST-PROVIDER_AUTHORIZATION_URL']; + delete process.env['OIDC_PROVIDER_TEST-PROVIDER_TOKEN_URL']; + delete process.env['OIDC_PROVIDER_TEST-PROVIDER_USERINFO_URL']; + delete process.env['OIDC_PROVIDER_TEST-PROVIDER_REDIRECT_URL']; + delete process.env['OIDC_PROVIDER_TEST-PROVIDER_REFRESH_TOKEN_URL']; + delete process.env['OIDC_PROVIDER_TEST-PROVIDER_LOGOUT_URL']; +}; diff --git a/test/fixtures/rse-fixtures.ts b/test/fixtures/rse-fixtures.ts index 3934a8594..2ea7391db 100644 --- a/test/fixtures/rse-fixtures.ts +++ b/test/fixtures/rse-fixtures.ts @@ -1,25 +1,596 @@ export const rses = { -"SWIFT": { "deterministic": true, "time_zone": null, "availability_delete": true, "volatile": false, "ISP": null, "qos_class": null, "staging_area": false, "ASN": null, "deleted": false, "id": "b93ea145172c40c68aeb6934cc597892", "city": null, "longitude": null, "deleted_at": null, "region_code": null, "latitude": null, "created_at": "Mon, 04 Dec 2023 19:04:47 UTC", "rse": "SWIFT", "country_name": null, "availability": 7, "updated_at": "Mon, 04 Dec 2023 19:04:47 UTC", "vo": "def", "continent": null, "availability_read": true, "rse_type": "DISK", "availability_write": true }, -"AMAZON-BOTO": { "deterministic": true, "time_zone": null, "availability_delete": true, "volatile": false, "ISP": null, "qos_class": null, "staging_area": false, "ASN": null, "deleted": false, "id": "1eb04b1b1a684dc6aa7be8062ecf4188", "city": null, "longitude": null, "deleted_at": null, "region_code": null, "latitude": null, "created_at": "Mon, 04 Dec 2023 19:04:47 UTC", "rse": "AMAZON-BOTO", "country_name": null, "availability": 7, "updated_at": "Mon, 04 Dec 2023 19:04:47 UTC", "vo": "def", "continent": null, "availability_read": true, "rse_type": "DISK", "availability_write": true }, -"BNL-BOTO": { "deterministic": true, "time_zone": null, "availability_delete": true, "volatile": false, "ISP": null, "qos_class": null, "staging_area": false, "ASN": null, "deleted": false, "id": "e8475b7bb5394909a8f7624975e96173", "city": null, "longitude": null, "deleted_at": null, "region_code": null, "latitude": null, "created_at": "Mon, 04 Dec 2023 19:04:47 UTC", "rse": "BNL-BOTO", "country_name": null, "availability": 7, "updated_at": "Mon, 04 Dec 2023 19:04:47 UTC", "vo": "def", "continent": null, "availability_read": true, "rse_type": "DISK", "availability_write": true }, -"CERN-S3-LOGS": { "deterministic": true, "time_zone": null, "availability_delete": true, "volatile": false, "ISP": null, "qos_class": null, "staging_area": false, "ASN": null, "deleted": false, "id": "71f020ed81f0493694b6c247d9f61942", "city": null, "longitude": null, "deleted_at": null, "region_code": null, "latitude": null, "created_at": "Mon, 04 Dec 2023 19:04:47 UTC", "rse": "CERN-S3-LOGS", "country_name": null, "availability": 7, "updated_at": "Mon, 04 Dec 2023 19:04:47 UTC", "vo": "def", "continent": null, "availability_read": true, "rse_type": "DISK", "availability_write": true }, -"LXPLUS": { "deterministic": true, "time_zone": null, "availability_delete": true, "volatile": false, "ISP": null, "qos_class": null, "staging_area": false, "ASN": null, "deleted": false, "id": "6ecc04be2c3d46eeaa384c8f2aa5328c", "city": null, "longitude": null, "deleted_at": null, "region_code": null, "latitude": null, "created_at": "Mon, 04 Dec 2023 19:04:48 UTC", "rse": "LXPLUS", "country_name": null, "availability": 7, "updated_at": "Mon, 04 Dec 2023 19:04:48 UTC", "vo": "def", "continent": null, "availability_read": true, "rse_type": "DISK", "availability_write": true }, -"MOCK-POSIX": { "deterministic": true, "time_zone": null, "availability_delete": true, "volatile": false, "ISP": null, "qos_class": null, "staging_area": false, "ASN": null, "deleted": false, "id": "66f45e2c413548a1a01765a52afc968a", "city": null, "longitude": null, "deleted_at": null, "region_code": null, "latitude": null, "created_at": "Mon, 04 Dec 2023 19:04:48 UTC", "rse": "MOCK-POSIX", "country_name": null, "availability": 7, "updated_at": "Mon, 04 Dec 2023 19:04:48 UTC", "vo": "def", "continent": null, "availability_read": true, "rse_type": "DISK", "availability_write": true }, -"MOCK": { "deterministic": true, "time_zone": null, "availability_delete": true, "volatile": false, "ISP": "Brookhaven National Laboratory", "qos_class": null, "staging_area": false, "ASN": null, "deleted": false, "id": "f57b54c5be394567b8cf69cae8c23ac8", "city": null, "longitude": null, "deleted_at": null, "region_code": null, "latitude": null, "created_at": "Mon, 04 Dec 2023 19:04:48 UTC", "rse": "MOCK", "country_name": "United States", "availability": 7, "updated_at": "Mon, 04 Dec 2023 19:04:48 UTC", "vo": "def", "continent": "NA", "availability_read": true, "rse_type": "DISK", "availability_write": true }, -"MOCK2": { "deterministic": false, "time_zone": "Europe/Zurich", "availability_delete": true, "volatile": false, "ISP": "CERN- LHC", "qos_class": null, "staging_area": false, "ASN": null, "deleted": false, "id": "0679030b5af64768aab8a28e1b92d037", "city": null, "longitude": null, "deleted_at": null, "region_code": "07", "latitude": null, "created_at": "Mon, 04 Dec 2023 19:04:48 UTC", "rse": "MOCK2", "country_name": "Switzerland", "availability": 7, "updated_at": "Mon, 04 Dec 2023 19:04:48 UTC", "vo": "def", "continent": "EU", "availability_read": true, "rse_type": "DISK", "availability_write": true }, -"MOCK3": { "deterministic": true, "time_zone": "Europe/Zurich", "availability_delete": true, "volatile": false, "ISP": "CERN- LHC", "qos_class": null, "staging_area": false, "ASN": null, "deleted": false, "id": "4e3f74e299e14039a18e6e6d8e5f41d1", "city": null, "longitude": null, "deleted_at": null, "region_code": "07", "latitude": null, "created_at": "Mon, 04 Dec 2023 19:04:48 UTC", "rse": "MOCK3", "country_name": "Switzerland", "availability": 7, "updated_at": "Mon, 04 Dec 2023 19:04:48 UTC", "vo": "def", "continent": "EU", "availability_read": true, "rse_type": "DISK", "availability_write": true }, -"MOCK4": { "deterministic": true, "time_zone": null, "availability_delete": true, "volatile": false, "ISP": null, "qos_class": null, "staging_area": false, "ASN": null, "deleted": false, "id": "c166021c007f48c8869942931bd4917c", "city": null, "longitude": null, "deleted_at": null, "region_code": null, "latitude": null, "created_at": "Mon, 04 Dec 2023 19:04:48 UTC", "rse": "MOCK4", "country_name": null, "availability": 7, "updated_at": "Mon, 04 Dec 2023 19:04:48 UTC", "vo": "def", "continent": null, "availability_read": true, "rse_type": "DISK", "availability_write": true }, -"MOCK5": { "deterministic": true, "time_zone": null, "availability_delete": true, "volatile": false, "ISP": null, "qos_class": null, "staging_area": false, "ASN": null, "deleted": false, "id": "78fb3b723e0146709a7b820bda42197f", "city": null, "longitude": null, "deleted_at": null, "region_code": null, "latitude": null, "created_at": "Mon, 04 Dec 2023 19:04:48 UTC", "rse": "MOCK5", "country_name": null, "availability": 7, "updated_at": "Mon, 04 Dec 2023 19:04:48 UTC", "vo": "def", "continent": null, "availability_read": true, "rse_type": "DISK", "availability_write": true }, -"MOCK_SUSPICIOUS": { "deterministic": true, "time_zone": null, "availability_delete": true, "volatile": false, "ISP": null, "qos_class": null, "staging_area": false, "ASN": null, "deleted": false, "id": "af3b2df57e4e4d539765c08ff79f984f", "city": null, "longitude": null, "deleted_at": null, "region_code": null, "latitude": null, "created_at": "Mon, 04 Dec 2023 19:04:48 UTC", "rse": "MOCK_SUSPICIOUS", "country_name": null, "availability": 7, "updated_at": "Mon, 04 Dec 2023 19:04:48 UTC", "vo": "def", "continent": null, "availability_read": true, "rse_type": "DISK", "availability_write": true }, -"MOCK_RECOVERY": { "deterministic": true, "time_zone": null, "availability_delete": true, "volatile": false, "ISP": null, "qos_class": null, "staging_area": false, "ASN": null, "deleted": false, "id": "0409e3be93ba4f89a928db364f93e34f", "city": null, "longitude": null, "deleted_at": null, "region_code": null, "latitude": null, "created_at": "Mon, 04 Dec 2023 19:04:48 UTC", "rse": "MOCK_RECOVERY", "country_name": null, "availability": 7, "updated_at": "Mon, 04 Dec 2023 19:04:48 UTC", "vo": "def", "continent": null, "availability_read": true, "rse_type": "DISK", "availability_write": true }, -"FZK-LCG2_SCRATCHDISK": { "deterministic": true, "time_zone": null, "availability_delete": true, "volatile": false, "ISP": null, "qos_class": null, "staging_area": false, "ASN": null, "deleted": false, "id": "71c136a02a8b4037babaaabe7c73c974", "city": null, "longitude": null, "deleted_at": null, "region_code": null, "latitude": null, "created_at": "Mon, 04 Dec 2023 19:04:48 UTC", "rse": "FZK-LCG2_SCRATCHDISK", "country_name": null, "availability": 7, "updated_at": "Mon, 04 Dec 2023 19:04:48 UTC", "vo": "def", "continent": null, "availability_read": true, "rse_type": "DISK", "availability_write": true }, -"CERN-PROD_TZERO": { "deterministic": false, "time_zone": null, "availability_delete": true, "volatile": false, "ISP": null, "qos_class": null, "staging_area": false, "ASN": null, "deleted": false, "id": "70764db7249446af913f0a95c0ce1e91", "city": null, "longitude": null, "deleted_at": null, "region_code": null, "latitude": null, "created_at": "Mon, 04 Dec 2023 19:04:48 UTC", "rse": "CERN-PROD_TZERO", "country_name": null, "availability": 7, "updated_at": "Mon, 04 Dec 2023 19:04:48 UTC", "vo": "def", "continent": null, "availability_read": true, "rse_type": "DISK", "availability_write": true }, -"WJ-XROOTD": { "deterministic": true, "time_zone": null, "availability_delete": true, "volatile": false, "ISP": null, "qos_class": null, "staging_area": false, "ASN": null, "deleted": false, "id": "5ca8bca0a1e345e68995be83d2a05e6a", "city": null, "longitude": null, "deleted_at": null, "region_code": null, "latitude": null, "created_at": "Mon, 04 Dec 2023 19:04:48 UTC", "rse": "WJ-XROOTD", "country_name": null, "availability": 7, "updated_at": "Mon, 04 Dec 2023 19:04:48 UTC", "vo": "def", "continent": null, "availability_read": true, "rse_type": "DISK", "availability_write": true }, -"SSH-DISK": { "deterministic": true, "time_zone": null, "availability_delete": true, "volatile": false, "ISP": null, "qos_class": null, "staging_area": false, "ASN": null, "deleted": false, "id": "01f9927cba8f4b41a8c253ab80d28dad", "city": null, "longitude": null, "deleted_at": null, "region_code": null, "latitude": null, "created_at": "Mon, 04 Dec 2023 19:04:48 UTC", "rse": "SSH-DISK", "country_name": null, "availability": 7, "updated_at": "Mon, 04 Dec 2023 19:04:48 UTC", "vo": "def", "continent": null, "availability_read": true, "rse_type": "DISK", "availability_write": true }, -"XRD1": { "deterministic": true, "time_zone": null, "availability_delete": true, "volatile": false, "ISP": null, "qos_class": null, "staging_area": false, "ASN": null, "deleted": false, "id": "c0f70d73c80a428db759fcc113e291e6", "city": null, "longitude": null, "deleted_at": null, "region_code": null, "latitude": null, "created_at": "Mon, 04 Dec 2023 19:04:52 UTC", "rse": "XRD1", "country_name": null, "availability": 7, "updated_at": "Mon, 04 Dec 2023 19:04:52 UTC", "vo": "def", "continent": null, "availability_read": true, "rse_type": "DISK", "availability_write": true }, -"XRD2": { "deterministic": true, "time_zone": null, "availability_delete": true, "volatile": false, "ISP": null, "qos_class": null, "staging_area": false, "ASN": null, "deleted": false, "id": "f4131ac29d9540bf9301b835d8caf22b", "city": null, "longitude": null, "deleted_at": null, "region_code": null, "latitude": null, "created_at": "Mon, 04 Dec 2023 19:04:53 UTC", "rse": "XRD2", "country_name": null, "availability": 7, "updated_at": "Mon, 04 Dec 2023 19:04:53 UTC", "vo": "def", "continent": null, "availability_read": true, "rse_type": "DISK", "availability_write": true }, -"XRD3": { "deterministic": true, "time_zone": null, "availability_delete": true, "volatile": false, "ISP": null, "qos_class": null, "staging_area": false, "ASN": null, "deleted": false, "id": "30d4e2d454d64e62b808bdd21208f30d", "city": null, "longitude": null, "deleted_at": null, "region_code": null, "latitude": null, "created_at": "Mon, 04 Dec 2023 19:04:55 UTC", "rse": "XRD3", "country_name": null, "availability": 7, "updated_at": "Mon, 04 Dec 2023 19:04:55 UTC", "vo": "def", "continent": null, "availability_read": true, "rse_type": "DISK", "availability_write": true }, -"XRD4": { "deterministic": true, "time_zone": null, "availability_delete": true, "volatile": false, "ISP": null, "qos_class": null, "staging_area": false, "ASN": null, "deleted": false, "id": "7c90be844af34d8b820a5ae5601b229c", "city": null, "longitude": null, "deleted_at": null, "region_code": null, "latitude": null, "created_at": "Mon, 04 Dec 2023 19:04:56 UTC", "rse": "XRD4", "country_name": null, "availability": 7, "updated_at": "Mon, 04 Dec 2023 19:04:56 UTC", "vo": "def", "continent": null, "availability_read": true, "rse_type": "DISK", "availability_write": true }, -"SSH1": { "deterministic": true, "time_zone": null, "availability_delete": true, "volatile": false, "ISP": null, "qos_class": null, "staging_area": false, "ASN": null, "deleted": false, "id": "e795214e0f634e3f92624ad446d622e9", "city": null, "longitude": null, "deleted_at": null, "region_code": null, "latitude": null, "created_at": "Mon, 04 Dec 2023 19:04:58 UTC", "rse": "SSH1", "country_name": null, "availability": 7, "updated_at": "Mon, 04 Dec 2023 19:04:58 UTC", "vo": "def", "continent": null, "availability_read": true, "rse_type": "DISK", "availability_write": true }, -} - + SWIFT: { + deterministic: true, + time_zone: null, + availability_delete: true, + volatile: false, + ISP: null, + qos_class: null, + staging_area: false, + ASN: null, + deleted: false, + id: 'b93ea145172c40c68aeb6934cc597892', + city: null, + longitude: null, + deleted_at: null, + region_code: null, + latitude: null, + created_at: 'Mon, 04 Dec 2023 19:04:47 UTC', + rse: 'SWIFT', + country_name: null, + availability: 7, + updated_at: 'Mon, 04 Dec 2023 19:04:47 UTC', + vo: 'def', + continent: null, + availability_read: true, + rse_type: 'DISK', + availability_write: true, + }, + 'AMAZON-BOTO': { + deterministic: true, + time_zone: null, + availability_delete: true, + volatile: false, + ISP: null, + qos_class: null, + staging_area: false, + ASN: null, + deleted: false, + id: '1eb04b1b1a684dc6aa7be8062ecf4188', + city: null, + longitude: null, + deleted_at: null, + region_code: null, + latitude: null, + created_at: 'Mon, 04 Dec 2023 19:04:47 UTC', + rse: 'AMAZON-BOTO', + country_name: null, + availability: 7, + updated_at: 'Mon, 04 Dec 2023 19:04:47 UTC', + vo: 'def', + continent: null, + availability_read: true, + rse_type: 'DISK', + availability_write: true, + }, + 'BNL-BOTO': { + deterministic: true, + time_zone: null, + availability_delete: true, + volatile: false, + ISP: null, + qos_class: null, + staging_area: false, + ASN: null, + deleted: false, + id: 'e8475b7bb5394909a8f7624975e96173', + city: null, + longitude: null, + deleted_at: null, + region_code: null, + latitude: null, + created_at: 'Mon, 04 Dec 2023 19:04:47 UTC', + rse: 'BNL-BOTO', + country_name: null, + availability: 7, + updated_at: 'Mon, 04 Dec 2023 19:04:47 UTC', + vo: 'def', + continent: null, + availability_read: true, + rse_type: 'DISK', + availability_write: true, + }, + 'CERN-S3-LOGS': { + deterministic: true, + time_zone: null, + availability_delete: true, + volatile: false, + ISP: null, + qos_class: null, + staging_area: false, + ASN: null, + deleted: false, + id: '71f020ed81f0493694b6c247d9f61942', + city: null, + longitude: null, + deleted_at: null, + region_code: null, + latitude: null, + created_at: 'Mon, 04 Dec 2023 19:04:47 UTC', + rse: 'CERN-S3-LOGS', + country_name: null, + availability: 7, + updated_at: 'Mon, 04 Dec 2023 19:04:47 UTC', + vo: 'def', + continent: null, + availability_read: true, + rse_type: 'DISK', + availability_write: true, + }, + LXPLUS: { + deterministic: true, + time_zone: null, + availability_delete: true, + volatile: false, + ISP: null, + qos_class: null, + staging_area: false, + ASN: null, + deleted: false, + id: '6ecc04be2c3d46eeaa384c8f2aa5328c', + city: null, + longitude: null, + deleted_at: null, + region_code: null, + latitude: null, + created_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + rse: 'LXPLUS', + country_name: null, + availability: 7, + updated_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + vo: 'def', + continent: null, + availability_read: true, + rse_type: 'DISK', + availability_write: true, + }, + 'MOCK-POSIX': { + deterministic: true, + time_zone: null, + availability_delete: true, + volatile: false, + ISP: null, + qos_class: null, + staging_area: false, + ASN: null, + deleted: false, + id: '66f45e2c413548a1a01765a52afc968a', + city: null, + longitude: null, + deleted_at: null, + region_code: null, + latitude: null, + created_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + rse: 'MOCK-POSIX', + country_name: null, + availability: 7, + updated_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + vo: 'def', + continent: null, + availability_read: true, + rse_type: 'DISK', + availability_write: true, + }, + MOCK: { + deterministic: true, + time_zone: null, + availability_delete: true, + volatile: false, + ISP: 'Brookhaven National Laboratory', + qos_class: null, + staging_area: false, + ASN: null, + deleted: false, + id: 'f57b54c5be394567b8cf69cae8c23ac8', + city: null, + longitude: null, + deleted_at: null, + region_code: null, + latitude: null, + created_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + rse: 'MOCK', + country_name: 'United States', + availability: 7, + updated_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + vo: 'def', + continent: 'NA', + availability_read: true, + rse_type: 'DISK', + availability_write: true, + }, + MOCK2: { + deterministic: false, + time_zone: 'Europe/Zurich', + availability_delete: true, + volatile: false, + ISP: 'CERN- LHC', + qos_class: null, + staging_area: false, + ASN: null, + deleted: false, + id: '0679030b5af64768aab8a28e1b92d037', + city: null, + longitude: null, + deleted_at: null, + region_code: '07', + latitude: null, + created_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + rse: 'MOCK2', + country_name: 'Switzerland', + availability: 7, + updated_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + vo: 'def', + continent: 'EU', + availability_read: true, + rse_type: 'DISK', + availability_write: true, + }, + MOCK3: { + deterministic: true, + time_zone: 'Europe/Zurich', + availability_delete: true, + volatile: false, + ISP: 'CERN- LHC', + qos_class: null, + staging_area: false, + ASN: null, + deleted: false, + id: '4e3f74e299e14039a18e6e6d8e5f41d1', + city: null, + longitude: null, + deleted_at: null, + region_code: '07', + latitude: null, + created_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + rse: 'MOCK3', + country_name: 'Switzerland', + availability: 7, + updated_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + vo: 'def', + continent: 'EU', + availability_read: true, + rse_type: 'DISK', + availability_write: true, + }, + MOCK4: { + deterministic: true, + time_zone: null, + availability_delete: true, + volatile: false, + ISP: null, + qos_class: null, + staging_area: false, + ASN: null, + deleted: false, + id: 'c166021c007f48c8869942931bd4917c', + city: null, + longitude: null, + deleted_at: null, + region_code: null, + latitude: null, + created_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + rse: 'MOCK4', + country_name: null, + availability: 7, + updated_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + vo: 'def', + continent: null, + availability_read: true, + rse_type: 'DISK', + availability_write: true, + }, + MOCK5: { + deterministic: true, + time_zone: null, + availability_delete: true, + volatile: false, + ISP: null, + qos_class: null, + staging_area: false, + ASN: null, + deleted: false, + id: '78fb3b723e0146709a7b820bda42197f', + city: null, + longitude: null, + deleted_at: null, + region_code: null, + latitude: null, + created_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + rse: 'MOCK5', + country_name: null, + availability: 7, + updated_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + vo: 'def', + continent: null, + availability_read: true, + rse_type: 'DISK', + availability_write: true, + }, + MOCK_SUSPICIOUS: { + deterministic: true, + time_zone: null, + availability_delete: true, + volatile: false, + ISP: null, + qos_class: null, + staging_area: false, + ASN: null, + deleted: false, + id: 'af3b2df57e4e4d539765c08ff79f984f', + city: null, + longitude: null, + deleted_at: null, + region_code: null, + latitude: null, + created_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + rse: 'MOCK_SUSPICIOUS', + country_name: null, + availability: 7, + updated_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + vo: 'def', + continent: null, + availability_read: true, + rse_type: 'DISK', + availability_write: true, + }, + MOCK_RECOVERY: { + deterministic: true, + time_zone: null, + availability_delete: true, + volatile: false, + ISP: null, + qos_class: null, + staging_area: false, + ASN: null, + deleted: false, + id: '0409e3be93ba4f89a928db364f93e34f', + city: null, + longitude: null, + deleted_at: null, + region_code: null, + latitude: null, + created_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + rse: 'MOCK_RECOVERY', + country_name: null, + availability: 7, + updated_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + vo: 'def', + continent: null, + availability_read: true, + rse_type: 'DISK', + availability_write: true, + }, + 'FZK-LCG2_SCRATCHDISK': { + deterministic: true, + time_zone: null, + availability_delete: true, + volatile: false, + ISP: null, + qos_class: null, + staging_area: false, + ASN: null, + deleted: false, + id: '71c136a02a8b4037babaaabe7c73c974', + city: null, + longitude: null, + deleted_at: null, + region_code: null, + latitude: null, + created_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + rse: 'FZK-LCG2_SCRATCHDISK', + country_name: null, + availability: 7, + updated_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + vo: 'def', + continent: null, + availability_read: true, + rse_type: 'DISK', + availability_write: true, + }, + 'CERN-PROD_TZERO': { + deterministic: false, + time_zone: null, + availability_delete: true, + volatile: false, + ISP: null, + qos_class: null, + staging_area: false, + ASN: null, + deleted: false, + id: '70764db7249446af913f0a95c0ce1e91', + city: null, + longitude: null, + deleted_at: null, + region_code: null, + latitude: null, + created_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + rse: 'CERN-PROD_TZERO', + country_name: null, + availability: 7, + updated_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + vo: 'def', + continent: null, + availability_read: true, + rse_type: 'DISK', + availability_write: true, + }, + 'WJ-XROOTD': { + deterministic: true, + time_zone: null, + availability_delete: true, + volatile: false, + ISP: null, + qos_class: null, + staging_area: false, + ASN: null, + deleted: false, + id: '5ca8bca0a1e345e68995be83d2a05e6a', + city: null, + longitude: null, + deleted_at: null, + region_code: null, + latitude: null, + created_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + rse: 'WJ-XROOTD', + country_name: null, + availability: 7, + updated_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + vo: 'def', + continent: null, + availability_read: true, + rse_type: 'DISK', + availability_write: true, + }, + 'SSH-DISK': { + deterministic: true, + time_zone: null, + availability_delete: true, + volatile: false, + ISP: null, + qos_class: null, + staging_area: false, + ASN: null, + deleted: false, + id: '01f9927cba8f4b41a8c253ab80d28dad', + city: null, + longitude: null, + deleted_at: null, + region_code: null, + latitude: null, + created_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + rse: 'SSH-DISK', + country_name: null, + availability: 7, + updated_at: 'Mon, 04 Dec 2023 19:04:48 UTC', + vo: 'def', + continent: null, + availability_read: true, + rse_type: 'DISK', + availability_write: true, + }, + XRD1: { + deterministic: true, + time_zone: null, + availability_delete: true, + volatile: false, + ISP: null, + qos_class: null, + staging_area: false, + ASN: null, + deleted: false, + id: 'c0f70d73c80a428db759fcc113e291e6', + city: null, + longitude: null, + deleted_at: null, + region_code: null, + latitude: null, + created_at: 'Mon, 04 Dec 2023 19:04:52 UTC', + rse: 'XRD1', + country_name: null, + availability: 7, + updated_at: 'Mon, 04 Dec 2023 19:04:52 UTC', + vo: 'def', + continent: null, + availability_read: true, + rse_type: 'DISK', + availability_write: true, + }, + XRD2: { + deterministic: true, + time_zone: null, + availability_delete: true, + volatile: false, + ISP: null, + qos_class: null, + staging_area: false, + ASN: null, + deleted: false, + id: 'f4131ac29d9540bf9301b835d8caf22b', + city: null, + longitude: null, + deleted_at: null, + region_code: null, + latitude: null, + created_at: 'Mon, 04 Dec 2023 19:04:53 UTC', + rse: 'XRD2', + country_name: null, + availability: 7, + updated_at: 'Mon, 04 Dec 2023 19:04:53 UTC', + vo: 'def', + continent: null, + availability_read: true, + rse_type: 'DISK', + availability_write: true, + }, + XRD3: { + deterministic: true, + time_zone: null, + availability_delete: true, + volatile: false, + ISP: null, + qos_class: null, + staging_area: false, + ASN: null, + deleted: false, + id: '30d4e2d454d64e62b808bdd21208f30d', + city: null, + longitude: null, + deleted_at: null, + region_code: null, + latitude: null, + created_at: 'Mon, 04 Dec 2023 19:04:55 UTC', + rse: 'XRD3', + country_name: null, + availability: 7, + updated_at: 'Mon, 04 Dec 2023 19:04:55 UTC', + vo: 'def', + continent: null, + availability_read: true, + rse_type: 'DISK', + availability_write: true, + }, + XRD4: { + deterministic: true, + time_zone: null, + availability_delete: true, + volatile: false, + ISP: null, + qos_class: null, + staging_area: false, + ASN: null, + deleted: false, + id: '7c90be844af34d8b820a5ae5601b229c', + city: null, + longitude: null, + deleted_at: null, + region_code: null, + latitude: null, + created_at: 'Mon, 04 Dec 2023 19:04:56 UTC', + rse: 'XRD4', + country_name: null, + availability: 7, + updated_at: 'Mon, 04 Dec 2023 19:04:56 UTC', + vo: 'def', + continent: null, + availability_read: true, + rse_type: 'DISK', + availability_write: true, + }, + SSH1: { + deterministic: true, + time_zone: null, + availability_delete: true, + volatile: false, + ISP: null, + qos_class: null, + staging_area: false, + ASN: null, + deleted: false, + id: 'e795214e0f634e3f92624ad446d622e9', + city: null, + longitude: null, + deleted_at: null, + region_code: null, + latitude: null, + created_at: 'Mon, 04 Dec 2023 19:04:58 UTC', + rse: 'SSH1', + country_name: null, + availability: 7, + updated_at: 'Mon, 04 Dec 2023 19:04:58 UTC', + vo: 'def', + continent: null, + availability_read: true, + rse_type: 'DISK', + availability_write: true, + }, +}; diff --git a/test/fixtures/rucio-server.ts b/test/fixtures/rucio-server.ts index c40beb209..a055d2a72 100644 --- a/test/fixtures/rucio-server.ts +++ b/test/fixtures/rucio-server.ts @@ -1,8 +1,8 @@ -import { HTTPRequest } from '@/lib/sdk/http' -import { Headers } from 'node-fetch' -import { Readable } from 'stream' -import { Response } from 'node-fetch' -import { BaseViewModel } from '@/lib/sdk/view-models' +import { HTTPRequest } from '@/lib/sdk/http'; +import { Headers } from 'node-fetch'; +import { Readable } from 'stream'; +import { Response } from 'node-fetch'; +import { BaseViewModel } from '@/lib/sdk/view-models'; /** * Represents a mock HTTP request endpoint. */ @@ -10,24 +10,24 @@ export interface MockEndpoint extends HTTPRequest { /** * A string that the URL must end with to match this endpoint. */ - endsWith?: string | null + endsWith?: string | null; /** * A string that the URL must include to match this endpoint. */ - includes?: string | null + includes?: string | null; /** * The response to send when this endpoint is matched. */ - response: MockGatewayResponse + response: MockGatewayResponse; /** * Validate the request parameters, body, and headers. * @param req The request to validate. * @returns undefined if the request is valid, otherwise a BaseViewModel with the error. */ - requestValidator?: (req: Request) => Promise + requestValidator?: (req: Request) => Promise; } /** @@ -37,19 +37,18 @@ export type MockGatewayResponse = { /** * The HTTP status code to return in the response. */ - status: number, + status: number; /** * The headers to include in the response. */ - headers: Headers | { [key: string]: string } | null, + headers: Headers | { [key: string]: string } | null; /** * The body of the response. */ - body: string | Readable | null -} - + body: string | Readable | null; +}; /** * A factory for creating mock Rucio servers. @@ -58,12 +57,12 @@ export default class MockRucioServerFactory { /** * A valid Rucio authentication token used by the Mock Rucio Server. */ - static VALID_RUCIO_TOKEN: string = 'rucio-ddmlab-askdjljioj' + static VALID_RUCIO_TOKEN: string = 'rucio-ddmlab-askdjljioj'; /** * The host URL for the Mock Rucio server. */ - static RUCIO_HOST: string = 'https://rucio-host.com' + static RUCIO_HOST: string = 'https://rucio-host.com'; /** * Creates a mock Rucio server with the specified endpoints. @@ -74,36 +73,37 @@ export default class MockRucioServerFactory { // @ts-ignore fetchMock.mockIf(/^https?:\/\/rucio-host.com.*$/, req => { if (checkAuth) { - const rucioToken = req.headers.get('X-Rucio-Auth-Token') + const rucioToken = req.headers.get('X-Rucio-Auth-Token'); if (rucioToken !== MockRucioServerFactory.VALID_RUCIO_TOKEN) { - return Promise.resolve(new Response('Invalid Rucio Auth Token', { - status: 401, - })) + return Promise.resolve( + new Response('Invalid Rucio Auth Token', { + status: 401, + }), + ); } } const endpoint = endpoints.find(endpoint => { - if(endpoint.url === req.url && endpoint.method === req.method) { - return true + if (endpoint.url === req.url && endpoint.method === req.method) { + return true; } - if(endpoint.endsWith && req.url.endsWith(endpoint.endsWith) && endpoint.method === req.method) { - return true + if (endpoint.endsWith && req.url.endsWith(endpoint.endsWith) && endpoint.method === req.method) { + return true; } - if(endpoint.includes && req.url.includes(endpoint.includes) && endpoint.method === req.method) { - return true + if (endpoint.includes && req.url.includes(endpoint.includes) && endpoint.method === req.method) { + return true; } - return false - }) - if(!endpoint) { + return false; + }); + if (!endpoint) { return Promise.resolve({ status: 404, - body: JSON.stringify('Not found') - } as MockGatewayResponse) + body: JSON.stringify('Not found'), + } as MockGatewayResponse); } - if(endpoint.requestValidator) { - endpoint.requestValidator(req) + if (endpoint.requestValidator) { + endpoint.requestValidator(req); } - return Promise.resolve(endpoint.response) - }) + return Promise.resolve(endpoint.response); + }); } } - \ No newline at end of file diff --git a/test/fixtures/stream-test-utils.ts b/test/fixtures/stream-test-utils.ts index d73955a04..d821469d9 100644 --- a/test/fixtures/stream-test-utils.ts +++ b/test/fixtures/stream-test-utils.ts @@ -1,14 +1,14 @@ -import { Transform } from 'stream' +import { Transform } from 'stream'; export async function collectStreamedData(stream: Transform | any): Promise { - const receivedData: TStreamData[] = [] + const receivedData: TStreamData[] = []; const onData = (data: TStreamData) => { - receivedData.push(data) - } + receivedData.push(data); + }; await new Promise((resolve, reject) => { - stream.on('data', onData) - stream.on('end', resolve) - stream.on('error', reject) + stream.on('data', onData); + stream.on('end', resolve); + stream.on('error', reject); }); - return receivedData -} \ No newline at end of file + return receivedData; +} diff --git a/test/fixtures/table-fixtures.ts b/test/fixtures/table-fixtures.ts index 2a0d83075..532f88844 100644 --- a/test/fixtures/table-fixtures.ts +++ b/test/fixtures/table-fixtures.ts @@ -1,18 +1,31 @@ -import { faker } from '@faker-js/faker' +import { faker } from '@faker-js/faker'; import { - LockState, DIDType, RuleNotification, RuleState, - RSEBlockState, SubscriptionState, + LockState, + DIDType, + RuleNotification, + RuleState, + RSEBlockState, + SubscriptionState, DIDAvailability, ReplicaState, RSEType, RSEProtocol, RSEAttribute, -} from '@/lib/core/entity/rucio' +} from '@/lib/core/entity/rucio'; import { RSEAccountUsageLimitViewModel, RSEAttributeViewModel, RSEProtocolViewModel, RSEViewModel } from '@/lib/infrastructure/data/view-model/rse'; import { UseComDOM } from '@/lib/infrastructure/hooks/useComDOM'; import { SubscriptionRuleStatesViewModel, SubscriptionViewModel } from '@/lib/infrastructure/data/view-model/subscriptions'; import { BaseViewModel } from '@/lib/sdk/view-models'; -import { DIDDatasetReplicasViewModel, DIDKeyValuePairsDataViewModel, DIDLongViewModel, DIDMetaViewModel, DIDRulesViewModel, DIDViewModel, FilereplicaStateDViewModel, FilereplicaStateViewModel } from '@/lib/infrastructure/data/view-model/did'; +import { + DIDDatasetReplicasViewModel, + DIDKeyValuePairsDataViewModel, + DIDLongViewModel, + DIDMetaViewModel, + DIDRulesViewModel, + DIDViewModel, + FilereplicaStateDViewModel, + FilereplicaStateViewModel, +} from '@/lib/infrastructure/data/view-model/did'; import { RuleMetaViewModel, RulePageLockEntryViewModel, RuleViewModel } from '@/lib/infrastructure/data/view-model/rule'; import { DIDKeyValuePair } from '@/lib/core/entity/rucio'; import { ListDIDsViewModel } from '@/lib/infrastructure/data/view-model/list-did'; @@ -22,88 +35,100 @@ export function mockUseComDOM(data: T[]): UseComDOM query: { data: { all: data, - success: data.filter((d) => d.status === "success"), - error: data.filter((d) => d.status === "error"), + success: data.filter(d => d.status === 'success'), + error: data.filter(d => d.status === 'error'), }, - fetchStatus: "idle", + fetchStatus: 'idle', }, - start: () => { }, - resume: () => { }, - pause: () => { }, - } as UseComDOM + start: () => {}, + resume: () => {}, + pause: () => {}, + } as UseComDOM; } -export function mockBaseVM(fail?: "none" | "some" | "all"): BaseViewModel { - const setting = fail ?? "none" +export function mockBaseVM(fail?: 'none' | 'some' | 'all'): BaseViewModel { + const setting = fail ?? 'none'; return { - status: setting === "none" ? "success" : ( - setting === "some" ? faker.helpers.arrayElement(["success", "error"]) : "error" - ), + status: setting === 'none' ? 'success' : setting === 'some' ? faker.helpers.arrayElement(['success', 'error']) : 'error', message: faker.lorem.words(3), - } + }; } function createRandomScope(): string { - return `user.${faker.person.firstName()}${faker.person.lastName()}` + return `user.${faker.person.firstName()}${faker.person.lastName()}`; } function randomEnum(e: any): T { - return faker.helpers.arrayElement(Object.values(e)) as T + return faker.helpers.arrayElement(Object.values(e)) as T; } export function createRSEName(): string { return ( - "RSE-" + - faker.location.country().toUpperCase().replace(/\s/g, "-").replace(/[^a-zA-Z\d\s]/g, "") + - "-" + + 'RSE-' + + faker.location + .country() + .toUpperCase() + .replace(/\s/g, '-') + .replace(/[^a-zA-Z\d\s]/g, '') + + '-' + faker.number.int({ max: 100 }) - ) + ); } function createRSEExpression(): string { - const creators = faker.helpers.arrayElements([ - () => { return "type" }, - () => { return "tier" }, - () => { return "country" }, - () => { return "region" }, - ] as Array<() => string>, { min: 1, max: 4 }) - const strings = creators.map((creator) => creator()) - return strings.join("&") + const creators = faker.helpers.arrayElements( + [ + () => { + return 'type'; + }, + () => { + return 'tier'; + }, + () => { + return 'country'; + }, + () => { + return 'region'; + }, + ] as Array<() => string>, + { min: 1, max: 4 }, + ); + const strings = creators.map(creator => creator()); + return strings.join('&'); } export function fixtureDIDViewModel(): DIDViewModel { return { ...mockBaseVM(), scope: createRandomScope(), - name: faker.lorem.words(3).replace(/\s/g, "."), + name: faker.lorem.words(3).replace(/\s/g, '.'), did_type: randomEnum(DIDType), - } + }; } export function fixtureDIDLongViewModel(): DIDLongViewModel { return { ...mockBaseVM(), scope: createRandomScope(), - name: faker.lorem.words(3).replace(/\s/g, "."), + name: faker.lorem.words(3).replace(/\s/g, '.'), did_type: randomEnum(DIDType), bytes: faker.number.int({ min: 0, max: 1e12 }), length: faker.number.int({ min: 0, max: 1e6 }), - } + }; } export function fixtureListDIDViewModel(): ListDIDsViewModel { return { ...mockBaseVM(), scope: createRandomScope(), - name: faker.lorem.words(3).replace(/\s/g, "."), + name: faker.lorem.words(3).replace(/\s/g, '.'), did_type: randomEnum(DIDType), bytes: faker.number.int({ min: 0, max: 1e12 }), length: faker.number.int({ min: 0, max: 1e6 }), open: faker.datatype.boolean(), - } + }; } - export function fixtureRulePageLockEntryViewModel(): RulePageLockEntryViewModel { return { ...mockBaseVM(), @@ -113,7 +138,7 @@ export function fixtureRulePageLockEntryViewModel(): RulePageLockEntryViewModel state: faker.helpers.arrayElement(['R', 'O', 'S', 'U']) as LockState, ddm_link: faker.internet.url(), fts_link: faker.internet.url(), - } + }; } export function fixtureRuleMetaViewModel(): RuleMetaViewModel { @@ -133,7 +158,7 @@ export function fixtureRuleMetaViewModel(): RuleMetaViewModel { locks_ok_cnt: faker.number.int({ min: 0, max: 10 }), locks_replicating_cnt: faker.number.int({ min: 0, max: 10 }), locks_stuck_cnt: faker.number.int({ min: 0, max: 10 }), - name: faker.lorem.words(3).replace(/\s/g, "."), + name: faker.lorem.words(3).replace(/\s/g, '.'), notification: randomEnum(RuleNotification), priority: faker.number.int({ min: 0, max: 3 }), purge_replicas: faker.datatype.boolean(), @@ -142,13 +167,13 @@ export function fixtureRuleMetaViewModel(): RuleMetaViewModel { split_container: faker.datatype.boolean(), state: randomEnum(RuleState), updated_at: faker.date.recent().toISOString(), - } + }; } export function fixtureRSEAccountUsageLimitViewModel(): RSEAccountUsageLimitViewModel { - const bytes_limit = faker.number.int({ min: 0, max: 1e12 }) - const used_bytes = faker.number.int({ min: 0, max: 1e12 }) - const has_quota = bytes_limit > used_bytes + const bytes_limit = faker.number.int({ min: 0, max: 1e12 }); + const used_bytes = faker.number.int({ min: 0, max: 1e12 }); + const has_quota = bytes_limit > used_bytes; return { ...mockBaseVM(), rse_id: faker.string.uuid(), @@ -160,7 +185,7 @@ export function fixtureRSEAccountUsageLimitViewModel(): RSEAccountUsageLimitView bytes_remaining: bytes_limit - used_bytes, has_quota: bytes_limit > used_bytes, total_expected_usage: faker.number.int({ min: 0, max: 1e12 }), - } + }; } export function fixtureRSEViewModel(): RSEViewModel { @@ -172,24 +197,24 @@ export function fixtureRSEViewModel(): RSEViewModel { deterministic: faker.datatype.boolean(), volatile: faker.datatype.boolean(), staging_area: faker.datatype.boolean(), - } + }; } export function fixtureRSEProtocolViewModel(): RSEProtocolViewModel { return { ...mockBaseVM(), protocols: Array.from({ length: faker.number.int({ min: 1, max: 100 }) }, () => fixtureRSEProtocol()), - } + }; } export function fixtureRSEProtocol(): RSEProtocol { return { rseid: faker.string.uuid(), - scheme: faker.helpers.arrayElement(["srm", "gsiftp", "root", "davs", "s3", "file"]), + scheme: faker.helpers.arrayElement(['srm', 'gsiftp', 'root', 'davs', 's3', 'file']), hostname: faker.internet.ip(), port: faker.number.int({ min: 0, max: 1e4 }), - prefix: faker.lorem.words(3).replace(/\s/g, "."), - impl: "rucio.rse.protocols.gfal.Default", + prefix: faker.lorem.words(3).replace(/\s/g, '.'), + impl: 'rucio.rse.protocols.gfal.Default', priorities_lan: { read: faker.number.int({ min: 0, max: 10 }), write: faker.number.int({ min: 0, max: 10 }), @@ -205,12 +230,12 @@ export function fixtureRSEProtocol(): RSEProtocol { }, updated_at: faker.date.recent().toISOString(), created_at: faker.date.past().toISOString(), - } + }; } export function fixtureRSEAttribute(): RSEAttribute { return { - key: faker.lorem.words(2).replace(/\s/g, "-"), + key: faker.lorem.words(2).replace(/\s/g, '-'), value: faker.helpers.arrayElement([ faker.lorem.words(3), faker.date.past().toISOString(), @@ -218,22 +243,21 @@ export function fixtureRSEAttribute(): RSEAttribute { faker.datatype.boolean(), null, ]), - } + }; } - export function fixtureRSEAttributeViewModel(): RSEAttributeViewModel { return { ...mockBaseVM(), attributes: Array.from({ length: faker.number.int({ min: 1, max: 100 }) }, () => fixtureRSEAttribute()), - } + }; } export function fixtureRuleViewModel(): RuleViewModel { return { ...mockBaseVM(), id: faker.string.uuid(), - name: faker.lorem.words(3).replace(/\s/g, "."), + name: faker.lorem.words(3).replace(/\s/g, '.'), account: faker.internet.userName(), rse_expression: createRSEExpression(), created_at: faker.date.past().toISOString(), @@ -242,15 +266,15 @@ export function fixtureRuleViewModel(): RuleViewModel { locks_ok_cnt: faker.number.int({ min: 0, max: 10 }), locks_replicating_cnt: faker.number.int({ min: 0, max: 10 }), locks_stuck_cnt: faker.number.int({ min: 0, max: 10 }), - } + }; } export function fixtureDIDMetaViewModel(): DIDMetaViewModel { // ignore Collections - const did_type = faker.helpers.arrayElement([DIDType.CONTAINER, DIDType.DATASET, DIDType.FILE]) + const did_type = faker.helpers.arrayElement([DIDType.CONTAINER, DIDType.DATASET, DIDType.FILE]); return { ...mockBaseVM(), - name: faker.lorem.words(3).replace(/\s/g, "."), + name: faker.lorem.words(3).replace(/\s/g, '.'), scope: createRandomScope(), account: faker.internet.userName(), did_type: did_type, @@ -265,33 +289,33 @@ export function fixtureDIDMetaViewModel(): DIDMetaViewModel { // only for collections is_open: did_type !== DIDType.FILE ? faker.datatype.boolean() : null, // only for files - adler32: did_type === DIDType.FILE ? faker.string.hexadecimal({ length: 8, prefix: "" }) : null, + adler32: did_type === DIDType.FILE ? faker.string.hexadecimal({ length: 8, prefix: '' }) : null, guid: did_type === DIDType.FILE ? faker.string.uuid() : null, - md5: did_type === DIDType.FILE ? faker.string.hexadecimal({ length: 32, prefix: "" }) : null, + md5: did_type === DIDType.FILE ? faker.string.hexadecimal({ length: 32, prefix: '' }) : null, bytes: did_type === DIDType.FILE ? faker.number.int({ min: 0, max: 1e12 }) : null, - } + }; } export function fixtureDIDKeyValuePair(): DIDKeyValuePair { return { - key: faker.lorem.words(2).replace(/\s/g, "-"), + key: faker.lorem.words(2).replace(/\s/g, '-'), value: faker.helpers.arrayElement([ - "das brot", + 'das brot', faker.date.past().toISOString(), faker.datatype.boolean(), faker.number.int({ min: 0, max: 1e6 }), null, - ]) - } + ]), + }; } export function fixtureDIDKeyValuePairsDataViewModel(): DIDKeyValuePairsDataViewModel { return { ...mockBaseVM(), data: Array.from({ length: 100 }, () => { - return fixtureDIDKeyValuePair() + return fixtureDIDKeyValuePair(); }), - } + }; } export function fixtureDIDDatasetReplicasViewModel(): DIDDatasetReplicasViewModel { @@ -304,19 +328,19 @@ export function fixtureDIDDatasetReplicasViewModel(): DIDDatasetReplicasViewMode available_bytes: faker.number.int({ min: 0, max: 1e12 }), creation_date: faker.date.past().toISOString(), last_accessed: faker.date.recent().toISOString(), - } + }; } export function fixtureDIDRulesViewModel(): DIDRulesViewModel { return { ...mockBaseVM(), id: faker.string.uuid(), - name: faker.lorem.words(3).replace(/\s/g, "."), + name: faker.lorem.words(3).replace(/\s/g, '.'), state: randomEnum(RuleState), account: faker.internet.userName(), - subscription: { name: faker.lorem.words(3).replace(/\s/g, "."), account: faker.internet.userName() }, + subscription: { name: faker.lorem.words(3).replace(/\s/g, '.'), account: faker.internet.userName() }, last_modified: faker.date.recent().toISOString(), - } + }; } export function fixtureFilereplicaStateViewModel(): FilereplicaStateViewModel { @@ -324,35 +348,34 @@ export function fixtureFilereplicaStateViewModel(): FilereplicaStateViewModel { ...mockBaseVM(), rse: createRSEName(), state: randomEnum(ReplicaState), - } + }; } export function fixtureFilereplicaStateDViewModel(): FilereplicaStateDViewModel { return { ...mockBaseVM(), scope: createRandomScope(), - name: faker.lorem.words(3).replace(/\s/g, "."), + name: faker.lorem.words(3).replace(/\s/g, '.'), available: faker.number.int({ min: 0, max: 10 }), unavailable: faker.number.int({ min: 0, max: 10 }), copying: faker.number.int({ min: 0, max: 10 }), being_deleted: faker.number.int({ min: 0, max: 10 }), bad: faker.number.int({ min: 0, max: 10 }), temporary_unavailable: faker.number.int({ min: 0, max: 10 }), - } + }; } export function fixtureSubscriptionRuleStatesViewModel(): SubscriptionRuleStatesViewModel { return { ...mockBaseVM(), - name: faker.lorem.words(3).replace(/\s/g, "."), + name: faker.lorem.words(3).replace(/\s/g, '.'), state_ok: faker.number.int({ min: 0, max: 10 }), state_replicating: faker.number.int({ min: 0, max: 10 }), state_stuck: faker.number.int({ min: 0, max: 10 }), state_suspended: faker.number.int({ min: 0, max: 10 }), state_waiting_approval: faker.number.int({ min: 0, max: 10 }), state_inject: faker.number.int({ min: 0, max: 10 }), - - } + }; } export function fixtureSubscriptionViewModel(): SubscriptionViewModel { @@ -363,43 +386,42 @@ export function fixtureSubscriptionViewModel(): SubscriptionViewModel { id: faker.string.uuid(), last_processed: faker.date.recent().toISOString(), lifetime: faker.date.future().toISOString(), - name: faker.lorem.words(3).replace(/\s/g, "."), + name: faker.lorem.words(3).replace(/\s/g, '.'), policyid: faker.number.int({ min: 0, max: 1e5 }), retroactive: faker.datatype.boolean(), state: randomEnum(SubscriptionState), updated_at: faker.date.recent().toISOString(), // more difficult datatypes: - filter: JSON.stringify({ - "scope": [ - createRandomScope() - ], - "project": [ - faker.commerce.productName() - ], - "split_rule": faker.datatype.boolean() - }, undefined, 2), + filter: JSON.stringify( + { + scope: [createRandomScope()], + project: [faker.commerce.productName()], + split_rule: faker.datatype.boolean(), + }, + undefined, + 2, + ), replication_rules: JSON.stringify( Array.from({ length: faker.number.int({ min: 1, max: 10 }) }, () => { return { - "activity": faker.company.buzzPhrase(), - "rse_expression": createRSEExpression(), - "source_replica_expression": createRSEExpression(), - "copies": "*", - "lifetime": 172800, - "comment": faker.lorem.words(10), - } + activity: faker.company.buzzPhrase(), + rse_expression: createRSEExpression(), + source_replica_expression: createRSEExpression(), + copies: '*', + lifetime: 172800, + comment: faker.lorem.words(10), + }; }), undefined, - 2 + 2, ), - } + }; } - export function generateSequenceArray(length: number, generator: () => any): any[] { const result: number[] = []; for (let i = 1; i <= length; i++) { result.push(generator()); } return result; -} \ No newline at end of file +} diff --git a/test/fixtures/widget-fixtures.ts b/test/fixtures/widget-fixtures.ts index 15dc1252c..76dd07b5a 100644 --- a/test/fixtures/widget-fixtures.ts +++ b/test/fixtures/widget-fixtures.ts @@ -1,6 +1,6 @@ -import { Ongoingrules, Usedquota } from "@/lib/core/entity/widgets"; -import { faker } from "@faker-js/faker"; -import { createRSEName } from "./table-fixtures"; +import { Ongoingrules, Usedquota } from '@/lib/core/entity/widgets'; +import { faker } from '@faker-js/faker'; +import { createRSEName } from './table-fixtures'; export function fixtureOngoingrules(): Ongoingrules { return { @@ -8,18 +8,18 @@ export function fixtureOngoingrules(): Ongoingrules { replicating: faker.number.int({ min: 0, max: 100 }), ok: faker.number.int({ min: 0, max: 100 }), stuck: faker.number.int({ min: 0, max: 100 }), - } + }; } export function fixtureUsedquota(): Usedquota { - const used = faker.number.int({min: 0, max: 100}) - const quota = faker.number.int({min: used, max: used + 100}) - const total = faker.number.int({min: quota, max: quota + 100}) + const used = faker.number.int({ min: 0, max: 100 }); + const quota = faker.number.int({ min: used, max: used + 100 }); + const total = faker.number.int({ min: quota, max: quota + 100 }); return { rse: createRSEName(), used: used, quota: quota, total: total, exceedPermission: faker.datatype.boolean(), - } -} \ No newline at end of file + }; +} diff --git a/test/gateway/account/account-gateway.test.ts b/test/gateway/account/account-gateway.test.ts index c0df487b2..a83c0d00f 100644 --- a/test/gateway/account/account-gateway.test.ts +++ b/test/gateway/account/account-gateway.test.ts @@ -1,22 +1,22 @@ -import { AccountAttributeErrorTypesDTO, AccountAttributesDTO } from "@/lib/core/dto/account-dto"; -import AccountGatewayOutputPort from "@/lib/core/port/secondary/account-gateway-output-port"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway"; -import { getIronSession } from "iron-session"; -import { createMocks } from "node-mocks-http"; +import { AccountAttributeErrorTypesDTO, AccountAttributesDTO } from '@/lib/core/dto/account-dto'; +import AccountGatewayOutputPort from '@/lib/core/port/secondary/account-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import { getIronSession } from 'iron-session'; +import { createMocks } from 'node-mocks-http'; -describe("Account Gateway Tests", () => { +describe('Account Gateway Tests', () => { beforeEach(() => { fetchMock.doMock(); - fetchMock.mockIf(/^https?:\/\/rucio-host.com.*$/, (req) => { + fetchMock.mockIf(/^https?:\/\/rucio-host.com.*$/, req => { if (req.url.endsWith('/accounts/ddmadmin/attr')) { - const rucioToken = req.headers.get('X-Rucio-Auth-Token') - if(rucioToken !== 'rucio-ddmlab-askdjljioj') { + const rucioToken = req.headers.get('X-Rucio-Auth-Token'); + if (rucioToken !== 'rucio-ddmlab-askdjljioj') { return Promise.resolve({ status: 401, - }) + }); } - expect(req.headers.get('X-Rucio-Auth-Token')).toBe('rucio-ddmlab-askdjljioj') + expect(req.headers.get('X-Rucio-Auth-Token')).toBe('rucio-ddmlab-askdjljioj'); return Promise.resolve({ status: 200, headers: { @@ -24,52 +24,52 @@ describe("Account Gateway Tests", () => { }, body: JSON.stringify([ { - "key": "admin", - "value": "True" + key: 'admin', + value: 'True', }, { - "key": "country-tw", - "value": "user" - } - ]) - }) + key: 'country-tw', + value: 'user', + }, + ]), + }); } - }) - }) + }); + }); afterEach(() => { fetchMock.dontMock(); - }) - test("it should return account attributes", async () => { - const rucioAccountGateway: AccountGatewayOutputPort = appContainer.get(GATEWAYS.ACCOUNT) - const accoutAttrs: AccountAttributesDTO = await rucioAccountGateway.listAccountAttributes('ddmadmin', 'rucio-ddmlab-askdjljioj') + }); + test('it should return account attributes', async () => { + const rucioAccountGateway: AccountGatewayOutputPort = appContainer.get(GATEWAYS.ACCOUNT); + const accoutAttrs: AccountAttributesDTO = await rucioAccountGateway.listAccountAttributes('ddmadmin', 'rucio-ddmlab-askdjljioj'); expect(accoutAttrs).toEqual({ status: 'OK', account: 'ddmadmin', attributes: [ { key: 'admin', - value: 'True' + value: 'True', }, { key: 'country-tw', - value: 'user' - } - ] - }) - }) - test("it should return authentication error with invalid token request", async () => { - const rucioAccountGateway: AccountGatewayOutputPort = appContainer.get(GATEWAYS.ACCOUNT) + value: 'user', + }, + ], + }); + }); + test('it should return authentication error with invalid token request', async () => { + const rucioAccountGateway: AccountGatewayOutputPort = appContainer.get(GATEWAYS.ACCOUNT); try { - const accoutAttrs: AccountAttributesDTO = await rucioAccountGateway.listAccountAttributes('ddmadmin', 'invalid-token') + const accoutAttrs: AccountAttributesDTO = await rucioAccountGateway.listAccountAttributes('ddmadmin', 'invalid-token'); } catch (error: AccountAttributesDTO | any) { - error.status = 'ERROR' + error.status = 'ERROR'; expect(error).toEqual({ status: 'ERROR', error: AccountAttributeErrorTypesDTO.RUCIO_AUTH_TOKEN_IS_INVALID_OR_EXPIRED, account: 'ddmadmin', attributes: {}, - message: 'Rucio Auth Token is invalid or expired' - }) + message: 'Rucio Auth Token is invalid or expired', + }); } - }) -}) \ No newline at end of file + }); +}); diff --git a/test/gateway/account/get-account-info.test.ts b/test/gateway/account/get-account-info.test.ts index 56d54b6db..81acfe66f 100644 --- a/test/gateway/account/get-account-info.test.ts +++ b/test/gateway/account/get-account-info.test.ts @@ -1,11 +1,11 @@ -import { AccountInfoDTO } from "@/lib/core/dto/account-dto"; -import { AccountStatus, AccountType } from "@/lib/core/entity/rucio"; -import AccountGatewayOutputPort from "@/lib/core/port/secondary/account-gateway-output-port"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway"; -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; +import { AccountInfoDTO } from '@/lib/core/dto/account-dto'; +import { AccountStatus, AccountType } from '@/lib/core/entity/rucio'; +import AccountGatewayOutputPort from '@/lib/core/port/secondary/account-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; -describe("Account Gateway: Get Account Info", () => { +describe('Account Gateway: Get Account Info', () => { beforeEach(() => { fetchMock.doMock(); const accountInfoEndpoint: MockEndpoint = { @@ -18,36 +18,35 @@ describe("Account Gateway: Get Account Info", () => { 'Content-Type': 'application/json', }, body: JSON.stringify({ - "status": "ACTIVE", - "deleted_at": null, - "updated_at": "2023-11-27T17:54:04", - "email": null, - "account_type": "SERVICE", - "suspended_at": null, - "account": "root", - "created_at": "2023-11-27T17:54:04" - }) - } - } + status: 'ACTIVE', + deleted_at: null, + updated_at: '2023-11-27T17:54:04', + email: null, + account_type: 'SERVICE', + suspended_at: null, + account: 'root', + created_at: '2023-11-27T17:54:04', + }), + }, + }; MockRucioServerFactory.createMockRucioServer(true, [accountInfoEndpoint]); - }) + }); afterEach(() => { fetchMock.dontMock(); - }) + }); - it("Should fetch account info for a given account", async () => { - const accountGateway: AccountGatewayOutputPort = appContainer.get(GATEWAYS.ACCOUNT) - const accountInfoDTO: AccountInfoDTO = await accountGateway.getAccountInfo('root', MockRucioServerFactory.VALID_RUCIO_TOKEN) - expect(accountInfoDTO.status).toEqual('success') - expect(accountInfoDTO.account).toEqual('root') - expect(accountInfoDTO.accountType).toEqual(AccountType.SERVICE) - expect(accountInfoDTO.email).toEqual("") - expect(accountInfoDTO.accountStatus).toEqual(AccountStatus.ACTIVE) - expect(accountInfoDTO.deletedAt).toEqual(undefined) - expect(accountInfoDTO.suspendedAt).toEqual(undefined) - expect(accountInfoDTO.createdAt).toEqual('2023-11-27T17:54:04') - expect(accountInfoDTO.updatedAt).toEqual('2023-11-27T17:54:04') - - }) -}) \ No newline at end of file + it('Should fetch account info for a given account', async () => { + const accountGateway: AccountGatewayOutputPort = appContainer.get(GATEWAYS.ACCOUNT); + const accountInfoDTO: AccountInfoDTO = await accountGateway.getAccountInfo('root', MockRucioServerFactory.VALID_RUCIO_TOKEN); + expect(accountInfoDTO.status).toEqual('success'); + expect(accountInfoDTO.account).toEqual('root'); + expect(accountInfoDTO.accountType).toEqual(AccountType.SERVICE); + expect(accountInfoDTO.email).toEqual(''); + expect(accountInfoDTO.accountStatus).toEqual(AccountStatus.ACTIVE); + expect(accountInfoDTO.deletedAt).toEqual(undefined); + expect(accountInfoDTO.suspendedAt).toEqual(undefined); + expect(accountInfoDTO.createdAt).toEqual('2023-11-27T17:54:04'); + expect(accountInfoDTO.updatedAt).toEqual('2023-11-27T17:54:04'); + }); +}); diff --git a/test/gateway/account/get-account-limits.test.ts b/test/gateway/account/get-account-limits.test.ts index cd230a4f2..eee287aab 100644 --- a/test/gateway/account/get-account-limits.test.ts +++ b/test/gateway/account/get-account-limits.test.ts @@ -1,11 +1,10 @@ -import { AccountRSELimitDTO, AccountRSEUsageDTO } from "@/lib/core/dto/account-dto"; -import AccountGatewayOutputPort from "@/lib/core/port/secondary/account-gateway-output-port"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway"; -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; - -describe("Account Gateway: Get Account Limits", () => { +import { AccountRSELimitDTO, AccountRSEUsageDTO } from '@/lib/core/dto/account-dto'; +import AccountGatewayOutputPort from '@/lib/core/port/secondary/account-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; +describe('Account Gateway: Get Account Limits', () => { beforeEach(() => { fetchMock.doMock(); const accountLimitEndpoint: MockEndpoint = { @@ -18,32 +17,32 @@ describe("Account Gateway: Get Account Limits", () => { 'Content-Type': 'application/json', }, body: JSON.stringify({ - "XRD1": 200, - "XRD2": Infinity, - "XRD3": Infinity, - "XRD4": -1, - "SSH1": -1 - }) - } - } + XRD1: 200, + XRD2: Infinity, + XRD3: Infinity, + XRD4: -1, + SSH1: -1, + }), + }, + }; MockRucioServerFactory.createMockRucioServer(true, [accountLimitEndpoint]); - }) + }); afterEach(() => { fetchMock.dontMock(); - }) + }); - it("Should fetch account limits for a given account", async () => { - const accountGateway: AccountGatewayOutputPort = appContainer.get(GATEWAYS.ACCOUNT) - const accountRSEUsageDTO: AccountRSELimitDTO = await accountGateway.getAccountRSELimits('root', MockRucioServerFactory.VALID_RUCIO_TOKEN) - expect(accountRSEUsageDTO.status).toEqual('success') - expect(accountRSEUsageDTO.account).toEqual('root') + it('Should fetch account limits for a given account', async () => { + const accountGateway: AccountGatewayOutputPort = appContainer.get(GATEWAYS.ACCOUNT); + const accountRSEUsageDTO: AccountRSELimitDTO = await accountGateway.getAccountRSELimits('root', MockRucioServerFactory.VALID_RUCIO_TOKEN); + expect(accountRSEUsageDTO.status).toEqual('success'); + expect(accountRSEUsageDTO.account).toEqual('root'); expect(accountRSEUsageDTO.limits).toEqual({ - "XRD1": 200, - "XRD2": Infinity, - "XRD3": Infinity, - "XRD4": Infinity, - "SSH1": Infinity - }) - }) -}); \ No newline at end of file + XRD1: 200, + XRD2: Infinity, + XRD3: Infinity, + XRD4: Infinity, + SSH1: Infinity, + }); + }); +}); diff --git a/test/gateway/account/list-account-rse-usage.test.ts b/test/gateway/account/list-account-rse-usage.test.ts index a5f9b2c77..928488c12 100644 --- a/test/gateway/account/list-account-rse-usage.test.ts +++ b/test/gateway/account/list-account-rse-usage.test.ts @@ -1,21 +1,58 @@ -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; -import { Readable } from "stream"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway"; -import AccountGatewayOutputPort from "@/lib/core/port/secondary/account-gateway-output-port"; -import { AccountRSEUsageDTO, ListAccountRSEUsageDTO } from "@/lib/core/dto/account-dto"; -import { collectStreamedData } from "test/fixtures/stream-test-utils"; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; +import { Readable } from 'stream'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import AccountGatewayOutputPort from '@/lib/core/port/secondary/account-gateway-output-port'; +import { AccountRSEUsageDTO, ListAccountRSEUsageDTO } from '@/lib/core/dto/account-dto'; +import { collectStreamedData } from 'test/fixtures/stream-test-utils'; describe('Account Gateway : List RSE Usage for an account', () => { beforeEach(() => { fetchMock.doMock(); - const rseStream = Readable.from([ - JSON.stringify({"rse_id": "d72884a3eb1747cf979af8959c978aab", "rse": "XRD2", "bytes": 100, "files": 2, "bytes_limit": 900, "bytes_remaining": 800}), - JSON.stringify({"rse_id": "5464fa3806324211ac5b490ce77acbfc", "rse": "SSH1", "bytes": 200, "files": 3, "bytes_limit": 800, "bytes_remaining": 600}), - JSON.stringify({"rse_id": "5883a989c9c047d99d2fc1c074e40f58", "rse": "XRD4", "bytes": 300, "files": 6, "bytes_limit": 700, "bytes_remaining": 400}), - JSON.stringify({"rse_id": "2bb03a45a1b64b459cdc445d9844d936", "rse": "XRD3", "bytes": 400, "files": 7, "bytes_limit": 600, "bytes_remaining": 200}), - JSON.stringify({"rse_id": "72fb4137ba3c460090bbd3fd8d490f8b", "rse": "XRD1", "bytes": 500, "files": 8, "bytes_limit": Infinity, "bytes_remaining": Infinity}), - ].join('\n') + '\n'); + const rseStream = Readable.from( + [ + JSON.stringify({ + rse_id: 'd72884a3eb1747cf979af8959c978aab', + rse: 'XRD2', + bytes: 100, + files: 2, + bytes_limit: 900, + bytes_remaining: 800, + }), + JSON.stringify({ + rse_id: '5464fa3806324211ac5b490ce77acbfc', + rse: 'SSH1', + bytes: 200, + files: 3, + bytes_limit: 800, + bytes_remaining: 600, + }), + JSON.stringify({ + rse_id: '5883a989c9c047d99d2fc1c074e40f58', + rse: 'XRD4', + bytes: 300, + files: 6, + bytes_limit: 700, + bytes_remaining: 400, + }), + JSON.stringify({ + rse_id: '2bb03a45a1b64b459cdc445d9844d936', + rse: 'XRD3', + bytes: 400, + files: 7, + bytes_limit: 600, + bytes_remaining: 200, + }), + JSON.stringify({ + rse_id: '72fb4137ba3c460090bbd3fd8d490f8b', + rse: 'XRD1', + bytes: 500, + files: 8, + bytes_limit: Infinity, + bytes_remaining: Infinity, + }), + ].join('\n') + '\n', + ); const listAccountRSEUsageEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/accounts/root/usage`, @@ -26,33 +63,36 @@ describe('Account Gateway : List RSE Usage for an account', () => { headers: { 'Content-Type': 'application/x-json-stream', }, - body: rseStream - } - } + body: rseStream, + }, + }; MockRucioServerFactory.createMockRucioServer(true, [listAccountRSEUsageEndpoint]); - }) + }); afterEach(() => { fetchMock.dontMock(); - }) + }); it('Should fetch a list of RSE Usage for a given account', async () => { - const accountGateway: AccountGatewayOutputPort = appContainer.get(GATEWAYS.ACCOUNT) - const listAcountRSEUsageDTO: ListAccountRSEUsageDTO = await accountGateway.listAccountRSEUsage('root', MockRucioServerFactory.VALID_RUCIO_TOKEN) - expect(listAcountRSEUsageDTO.status).toEqual('success') + const accountGateway: AccountGatewayOutputPort = appContainer.get(GATEWAYS.ACCOUNT); + const listAcountRSEUsageDTO: ListAccountRSEUsageDTO = await accountGateway.listAccountRSEUsage( + 'root', + MockRucioServerFactory.VALID_RUCIO_TOKEN, + ); + expect(listAcountRSEUsageDTO.status).toEqual('success'); - const accountRSEUsageStream = listAcountRSEUsageDTO.stream - if( accountRSEUsageStream == null || accountRSEUsageStream == undefined) { - fail('Account RSE Usage stream is null or undefined') + const accountRSEUsageStream = listAcountRSEUsageDTO.stream; + if (accountRSEUsageStream == null || accountRSEUsageStream == undefined) { + fail('Account RSE Usage stream is null or undefined'); } - const recievedData: AccountRSEUsageDTO[] = await collectStreamedData(accountRSEUsageStream) - expect(recievedData.length).toEqual(5) - expect(recievedData[0].rse_id).toEqual('d72884a3eb1747cf979af8959c978aab') - expect(recievedData[0].rse).toEqual('XRD2') - expect(recievedData[0].used_bytes).toEqual(100) - expect(recievedData[0].files).toEqual(2) - expect(recievedData[0].bytes_limit).toEqual(900) - }) -}); \ No newline at end of file + const recievedData: AccountRSEUsageDTO[] = await collectStreamedData(accountRSEUsageStream); + expect(recievedData.length).toEqual(5); + expect(recievedData[0].rse_id).toEqual('d72884a3eb1747cf979af8959c978aab'); + expect(recievedData[0].rse).toEqual('XRD2'); + expect(recievedData[0].used_bytes).toEqual(100); + expect(recievedData[0].files).toEqual(2); + expect(recievedData[0].bytes_limit).toEqual(900); + }); +}); diff --git a/test/gateway/did/did-gateway-add-attach-status.test.ts b/test/gateway/did/did-gateway-add-attach-status.test.ts index 23e0edb76..cf0964757 100644 --- a/test/gateway/did/did-gateway-add-attach-status.test.ts +++ b/test/gateway/did/did-gateway-add-attach-status.test.ts @@ -1,21 +1,21 @@ -import { AttachDIDDTO, CreateDIDSampleDTO, SetDIDStatusDTO } from "@/lib/core/dto/did-dto" -import { DIDType } from "@/lib/core/entity/rucio" -import DIDGatewayOutputPort from "@/lib/core/port/secondary/did-gateway-output-port" -import appContainer from "@/lib/infrastructure/ioc/container-config" -import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway" -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server" +import { AttachDIDDTO, CreateDIDSampleDTO, SetDIDStatusDTO } from '@/lib/core/dto/did-dto'; +import { DIDType } from '@/lib/core/entity/rucio'; +import DIDGatewayOutputPort from '@/lib/core/port/secondary/did-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; describe('DID Gateway Tests: Add DID, Attach DIDs, Set DIDStatus', () => { beforeEach(() => { - fetchMock.doMock() + fetchMock.doMock(); const addDIDEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/dids/test/conatiner10`, - endsWith: "/test/container10", + endsWith: '/test/container10', method: 'POST', - requestValidator: async(req: Request) => { - const body = await req.json() - if(body.type !== 'CONTAINER') { - throw new Error('Invalid DID Type') + requestValidator: async (req: Request) => { + const body = await req.json(); + if (body.type !== 'CONTAINER') { + throw new Error('Invalid DID Type'); } }, response: { @@ -23,87 +23,71 @@ describe('DID Gateway Tests: Add DID, Attach DIDs, Set DIDStatus', () => { headers: { 'Content-Type': 'text/html; charset=utf-8', }, - body: 'Created' - } - } + body: 'Created', + }, + }; const attachDIDEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/dids/test/dataset10/dids`, - endsWith: "/test/dataset10/dids", + endsWith: '/test/dataset10/dids', method: 'POST', response: { status: 201, headers: { 'Content-Type': 'text/html; charset=utf-8', }, - body: 'Created' - } - } + body: 'Created', + }, + }; const setStatusEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/dids/test/dataset10/status`, - endsWith: "/test/dataset10/status", + endsWith: '/test/dataset10/status', method: 'PUT', response: { status: 200, headers: { 'Content-Type': 'text/html; charset=utf-8', }, - body: null - } - } + body: null, + }, + }; MockRucioServerFactory.createMockRucioServer(true, [addDIDEndpoint, attachDIDEndpoint, setStatusEndpoint]); - }) + }); afterEach(() => { - fetchMock.dontMock() - }) + fetchMock.dontMock(); + }); it('should successfully hit the right Rucio Server endpoint when adding a new DID', async () => { - const rucioDIDGateway: DIDGatewayOutputPort = appContainer.get( - GATEWAYS.DID, - ) + const rucioDIDGateway: DIDGatewayOutputPort = appContainer.get(GATEWAYS.DID); const dto: CreateDIDSampleDTO = await rucioDIDGateway.addDID( MockRucioServerFactory.VALID_RUCIO_TOKEN, 'test', 'container10', - DIDType.CONTAINER - ) - expect(dto.status).toEqual('success') - expect(dto.created).toEqual(true) - }) + DIDType.CONTAINER, + ); + expect(dto.status).toEqual('success'); + expect(dto.created).toEqual(true); + }); it('should successfully hit the right Rucio Server endpoint when attaching DIDs to a new DID', async () => { - const rucioDIDGateway: DIDGatewayOutputPort = appContainer.get( - GATEWAYS.DID, - ) - const dto: AttachDIDDTO = await rucioDIDGateway.attachDIDs( - MockRucioServerFactory.VALID_RUCIO_TOKEN, - 'test', - 'dataset10', - [ - { - scope: 'test', - name: 'file1', - did_type: DIDType.FILE, - }, - { - scope: 'test', - name: 'file2', - did_type: DIDType.FILE, - }, - ] - ) - expect(dto.status).toEqual('success') - expect(dto.created).toEqual(true) - }) + const rucioDIDGateway: DIDGatewayOutputPort = appContainer.get(GATEWAYS.DID); + const dto: AttachDIDDTO = await rucioDIDGateway.attachDIDs(MockRucioServerFactory.VALID_RUCIO_TOKEN, 'test', 'dataset10', [ + { + scope: 'test', + name: 'file1', + did_type: DIDType.FILE, + }, + { + scope: 'test', + name: 'file2', + did_type: DIDType.FILE, + }, + ]); + expect(dto.status).toEqual('success'); + expect(dto.created).toEqual(true); + }); it('should successfully hit the right Rucio Server endpoint when setting the status of a DID', async () => { - const rucioDIDGateway: DIDGatewayOutputPort = appContainer.get( - GATEWAYS.DID, - ) - const dto: SetDIDStatusDTO = await rucioDIDGateway.setDIDStatus( - MockRucioServerFactory.VALID_RUCIO_TOKEN, - 'test', - 'dataset10', - false - ) - expect(dto.status).toEqual('success') - }) -}) \ No newline at end of file + const rucioDIDGateway: DIDGatewayOutputPort = appContainer.get(GATEWAYS.DID); + const dto: SetDIDStatusDTO = await rucioDIDGateway.setDIDStatus(MockRucioServerFactory.VALID_RUCIO_TOKEN, 'test', 'dataset10', false); + expect(dto.status).toEqual('success'); + }); +}); diff --git a/test/gateway/did/did-gateway-create-did-sample.test.ts b/test/gateway/did/did-gateway-create-did-sample.test.ts index d36b17aba..e2185707a 100644 --- a/test/gateway/did/did-gateway-create-did-sample.test.ts +++ b/test/gateway/did/did-gateway-create-did-sample.test.ts @@ -1,12 +1,12 @@ -import { CreateDIDSampleDTO } from "@/lib/core/dto/did-dto" -import DIDGatewayOutputPort from "@/lib/core/port/secondary/did-gateway-output-port" -import appContainer from "@/lib/infrastructure/ioc/container-config" -import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway" -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server" +import { CreateDIDSampleDTO } from '@/lib/core/dto/did-dto'; +import DIDGatewayOutputPort from '@/lib/core/port/secondary/did-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; describe('DID Gateway Tests Create DID Sample', () => { beforeEach(() => { - fetchMock.doMock() + fetchMock.doMock(); const createDIDSampleEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/dids/sample`, method: 'POST', @@ -15,30 +15,27 @@ describe('DID Gateway Tests Create DID Sample', () => { headers: { 'Content-Type': 'text/html; charset=utf-8', }, - body: 'Created' - } - } + body: 'Created', + }, + }; MockRucioServerFactory.createMockRucioServer(true, [createDIDSampleEndpoint]); - }) + }); afterEach(() => { - fetchMock.dontMock() - }) - + fetchMock.dontMock(); + }); + it('should successfully create DID Sample', async () => { - const rucioDIDGateway: DIDGatewayOutputPort = appContainer.get( - GATEWAYS.DID, - ) + const rucioDIDGateway: DIDGatewayOutputPort = appContainer.get(GATEWAYS.DID); const dto: CreateDIDSampleDTO = await rucioDIDGateway.createDIDSample( MockRucioServerFactory.VALID_RUCIO_TOKEN, 'test', 'dataset1', 'test', 'dataset10', - 2 - ) - expect(dto.status).toEqual('success') - expect(dto.created).toEqual(true) - - }) -}) \ No newline at end of file + 2, + ); + expect(dto.status).toEqual('success'); + expect(dto.created).toEqual(true); + }); +}); diff --git a/test/gateway/did/did-gateway-keyvaluepairs.test.ts b/test/gateway/did/did-gateway-keyvaluepairs.test.ts index 8e7270bc8..2f9494fdd 100644 --- a/test/gateway/did/did-gateway-keyvaluepairs.test.ts +++ b/test/gateway/did/did-gateway-keyvaluepairs.test.ts @@ -1,38 +1,38 @@ -import { DIDKeyValuePairsDTO } from "@/lib/core/dto/did-dto"; -import DIDGatewayOutputPort from "@/lib/core/port/secondary/did-gateway-output-port"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway"; -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; +import { DIDKeyValuePairsDTO } from '@/lib/core/dto/did-dto'; +import DIDGatewayOutputPort from '@/lib/core/port/secondary/did-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; -describe("DID Gateway KeyValuePairs Endpoint Tests", () => { +describe('DID Gateway KeyValuePairs Endpoint Tests', () => { beforeEach(() => { fetchMock.doMock(); const didKVMockEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/dids/test/dataset1/meta`, - method: "GET", - includes: "test/dataset1/meta", + method: 'GET', + includes: 'test/dataset1/meta', response: { status: 200, headers: { - "Content-Type": "application/json", + 'Content-Type': 'application/json', }, body: JSON.stringify({ - "scope": "test", - "name": "dataset1", - "extra_key": "extra_value", - }) - } - } + scope: 'test', + name: 'dataset1', + extra_key: 'extra_value', + }), + }, + }; MockRucioServerFactory.createMockRucioServer(true, [didKVMockEndpoint]); }); afterEach(() => { fetchMock.dontMock(); }); - it("should return a DIDKeyValuePairsDTO", async () => { - const didGateway: DIDGatewayOutputPort = appContainer.get(GATEWAYS.DID) - const dto: DIDKeyValuePairsDTO = await didGateway.getDIDKeyValuePairs(MockRucioServerFactory.VALID_RUCIO_TOKEN, "test", "dataset1") - expect(dto.status).toEqual("success") - expect(dto.data).toContainEqual({key: "extra_key", value: "extra_value"}) - expect(dto.data).toContainEqual({key: "scope", value: "test"}) + it('should return a DIDKeyValuePairsDTO', async () => { + const didGateway: DIDGatewayOutputPort = appContainer.get(GATEWAYS.DID); + const dto: DIDKeyValuePairsDTO = await didGateway.getDIDKeyValuePairs(MockRucioServerFactory.VALID_RUCIO_TOKEN, 'test', 'dataset1'); + expect(dto.status).toEqual('success'); + expect(dto.data).toContainEqual({ key: 'extra_key', value: 'extra_value' }); + expect(dto.data).toContainEqual({ key: 'scope', value: 'test' }); }); -}) +}); diff --git a/test/gateway/did/did-gateway-list-did-contents.test.ts b/test/gateway/did/did-gateway-list-did-contents.test.ts index 26b0d019d..998d2230d 100644 --- a/test/gateway/did/did-gateway-list-did-contents.test.ts +++ b/test/gateway/did/did-gateway-list-did-contents.test.ts @@ -1,12 +1,12 @@ -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; -import { Readable } from "stream"; -import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway"; -import DIDGatewayOutputPort from "@/lib/core/port/secondary/did-gateway-output-port"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import { DIDRulesDTO, ListDIDRulesDTO as ListDIDDTO } from "@/lib/core/dto/did-dto"; -import { DIDType, RuleState } from "@/lib/core/entity/rucio"; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; +import { Readable } from 'stream'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import DIDGatewayOutputPort from '@/lib/core/port/secondary/did-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import { DIDRulesDTO, ListDIDRulesDTO as ListDIDDTO } from '@/lib/core/dto/did-dto'; +import { DIDType, RuleState } from '@/lib/core/entity/rucio'; -describe("DID Gateway List DID Contents Endpoint Tests", () => { +describe('DID Gateway List DID Contents Endpoint Tests', () => { beforeEach(() => { fetchMock.doMock(); const didListContentsMockEndpoint: MockEndpoint = { @@ -20,12 +20,26 @@ describe("DID Gateway List DID Contents Endpoint Tests", () => { }, body: Readable.from( [ - JSON.stringify({"scope": "test", "name": "file1", "type": "FILE", "bytes": 10485760, "adler32": "517daa38", "md5": "e4319066a5d3771954652a6905cebe82"}), - JSON.stringify({"scope": "test", "name": "file2", "type": "FILE", "bytes": 10485760, "adler32": "fc6ff847", "md5": "bcc3619205bf64d3cbe984b27c042a01"}), - ].join('\n') - ) - } - } + JSON.stringify({ + scope: 'test', + name: 'file1', + type: 'FILE', + bytes: 10485760, + adler32: '517daa38', + md5: 'e4319066a5d3771954652a6905cebe82', + }), + JSON.stringify({ + scope: 'test', + name: 'file2', + type: 'FILE', + bytes: 10485760, + adler32: 'fc6ff847', + md5: 'bcc3619205bf64d3cbe984b27c042a01', + }), + ].join('\n'), + ), + }, + }; MockRucioServerFactory.createMockRucioServer(true, [didListContentsMockEndpoint]); }); @@ -34,43 +48,42 @@ describe("DID Gateway List DID Contents Endpoint Tests", () => { fetchMock.dontMock(); }); it('should successfully stream a list of files for a Dataset DID', async () => { - - const rucioDIDGateway: DIDGatewayOutputPort = appContainer.get(GATEWAYS.DID) - const dto: ListDIDDTO = await rucioDIDGateway.listDIDContents(MockRucioServerFactory.VALID_RUCIO_TOKEN, "test", "dataset1"); + const rucioDIDGateway: DIDGatewayOutputPort = appContainer.get(GATEWAYS.DID); + const dto: ListDIDDTO = await rucioDIDGateway.listDIDContents(MockRucioServerFactory.VALID_RUCIO_TOKEN, 'test', 'dataset1'); expect(dto.status).toBe('success'); - + const didContentsStream = dto.stream; expect(didContentsStream).toBeDefined(); - if( didContentsStream == null || didContentsStream == undefined) { + if (didContentsStream == null || didContentsStream == undefined) { fail('didContentsStream is null or undefined'); } - const receivedData: any[] = [] + const receivedData: any[] = []; const onData = (data: DIDRulesDTO) => { - receivedData.push(data) - } + receivedData.push(data); + }; await new Promise((resolve, reject) => { - didContentsStream.on('data', onData) - didContentsStream.on('end', resolve) - didContentsStream.on('error', reject) + didContentsStream.on('data', onData); + didContentsStream.on('end', resolve); + didContentsStream.on('error', reject); }); expect(receivedData.length).toBe(2); expect(receivedData).toEqual([ { - "status": "success", - "scope": "test", - "name": "file1", - "did_type": DIDType.FILE, + status: 'success', + scope: 'test', + name: 'file1', + did_type: DIDType.FILE, }, { - "status": "success", - "scope": "test", - "name": "file2", - "did_type": DIDType.FILE, - } - ]) + status: 'success', + scope: 'test', + name: 'file2', + did_type: DIDType.FILE, + }, + ]); }); -}); \ No newline at end of file +}); diff --git a/test/gateway/did/did-gateway-list-did-parent-endpoint.test.ts b/test/gateway/did/did-gateway-list-did-parent-endpoint.test.ts index e97d8095f..a871b8272 100644 --- a/test/gateway/did/did-gateway-list-did-parent-endpoint.test.ts +++ b/test/gateway/did/did-gateway-list-did-parent-endpoint.test.ts @@ -1,35 +1,37 @@ -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; -import { Readable } from "stream"; -import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway"; -import DIDGatewayOutputPort from "@/lib/core/port/secondary/did-gateway-output-port"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import { DIDRulesDTO, ListDIDRulesDTO } from "@/lib/core/dto/did-dto"; -import { DIDType, RuleState } from "@/lib/core/entity/rucio"; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; +import { Readable } from 'stream'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import DIDGatewayOutputPort from '@/lib/core/port/secondary/did-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import { DIDRulesDTO, ListDIDRulesDTO } from '@/lib/core/dto/did-dto'; +import { DIDType, RuleState } from '@/lib/core/entity/rucio'; -describe("DID Gateway List DID Parent Endpoint Tests", () => { +describe('DID Gateway List DID Parent Endpoint Tests', () => { beforeEach(() => { fetchMock.doMock(); const didListRulesMockEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/dids/test/file1/parents`, - method: "GET", - includes: "test/dataset1/rules", + method: 'GET', + includes: 'test/dataset1/rules', response: { status: 200, headers: { - "Content-Type": "application/x-json-stream", + 'Content-Type': 'application/x-json-stream', }, - body: Readable.from( [ - JSON.stringify({ - "scope": "test", - "name": "dataset1", - "type": "DATASET" - }), - JSON.stringify({ - "scope": "test", - "name": "dataset2", - "type": "DATASET" - }) - ].join("\n")), + body: Readable.from( + [ + JSON.stringify({ + scope: 'test', + name: 'dataset1', + type: 'DATASET', + }), + JSON.stringify({ + scope: 'test', + name: 'dataset2', + type: 'DATASET', + }), + ].join('\n'), + ), }, }; @@ -40,43 +42,42 @@ describe("DID Gateway List DID Parent Endpoint Tests", () => { fetchMock.dontMock(); }); it('should successfully stream a list of rules for a DID', async () => { - - const rucioDIDGateway: DIDGatewayOutputPort = appContainer.get(GATEWAYS.DID) - const dto: ListDIDRulesDTO = await rucioDIDGateway.listDIDParents(MockRucioServerFactory.VALID_RUCIO_TOKEN, "test", "file1"); + const rucioDIDGateway: DIDGatewayOutputPort = appContainer.get(GATEWAYS.DID); + const dto: ListDIDRulesDTO = await rucioDIDGateway.listDIDParents(MockRucioServerFactory.VALID_RUCIO_TOKEN, 'test', 'file1'); expect(dto.status).toBe('success'); - + const didParentsStream = dto.stream; expect(didParentsStream).toBeDefined(); - if( didParentsStream == null || didParentsStream == undefined) { + if (didParentsStream == null || didParentsStream == undefined) { fail('didParentsStream is null or undefined'); } - const receivedData: any[] = [] + const receivedData: any[] = []; const onData = (data: DIDRulesDTO) => { - receivedData.push(data) - } + receivedData.push(data); + }; await new Promise((resolve, reject) => { - didParentsStream.on('data', onData) - didParentsStream.on('end', resolve) - didParentsStream.on('error', reject) + didParentsStream.on('data', onData); + didParentsStream.on('end', resolve); + didParentsStream.on('error', reject); }); expect(receivedData.length).toBe(2); expect(receivedData).toEqual([ { - "status": "success", - "scope": "test", - "name": "dataset1", - "did_type": DIDType.DATASET, + status: 'success', + scope: 'test', + name: 'dataset1', + did_type: DIDType.DATASET, }, { - "status": "success", - "scope": "test", - "name": "dataset2", - "did_type": DIDType.DATASET, - } - ]) + status: 'success', + scope: 'test', + name: 'dataset2', + did_type: DIDType.DATASET, + }, + ]); }); -}); \ No newline at end of file +}); diff --git a/test/gateway/did/did-gateway-list-rules-endpoint.test.ts b/test/gateway/did/did-gateway-list-rules-endpoint.test.ts index aef29d448..f52ebd31b 100644 --- a/test/gateway/did/did-gateway-list-rules-endpoint.test.ts +++ b/test/gateway/did/did-gateway-list-rules-endpoint.test.ts @@ -1,27 +1,95 @@ -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; -import { Readable } from "stream"; -import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway"; -import DIDGatewayOutputPort from "@/lib/core/port/secondary/did-gateway-output-port"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import { DIDRulesDTO, ListDIDRulesDTO } from "@/lib/core/dto/did-dto"; -import { RuleState } from "@/lib/core/entity/rucio"; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; +import { Readable } from 'stream'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import DIDGatewayOutputPort from '@/lib/core/port/secondary/did-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import { DIDRulesDTO, ListDIDRulesDTO } from '@/lib/core/dto/did-dto'; +import { RuleState } from '@/lib/core/entity/rucio'; -describe("DID Gateway List Rules Endpoint Tests", () => { +describe('DID Gateway List Rules Endpoint Tests', () => { beforeEach(() => { fetchMock.doMock(); const didListRulesMockEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/dids/test/dataset1/rules`, - method: "GET", - includes: "test/dataset1/rules", + method: 'GET', + includes: 'test/dataset1/rules', response: { status: 200, headers: { - "Content-Type": "application/x-json-stream", + 'Content-Type': 'application/x-json-stream', }, - body: Readable.from( [ - JSON.stringify({"id":"dummy_id","subscription_id":"sample_subscription_007","account":"dummy_account","scope":"dummy_scope","name":"dummy_name","did_type":"DATASET","state":"OK","error":null,"rse_expression":"dummy_rse_expression","copies":1,"expires_at":null,"weight":null,"locked":true,"locks_ok_cnt":28635,"locks_replicating_cnt":0,"locks_stuck_cnt":0,"source_replica_expression":"dummy_source_replica_expression","activity":"dummy_activity","grouping":"DATASET","notification":"NO","stuck_at":null,"purge_replicas":false,"ignore_availability":true,"ignore_account_limit":false,"priority":3,"comments":null,"child_rule_id":null,"eol_at":null,"split_container":false,"meta":null,"created_at":"Fri, 09 Jun 2023 13:16:31 UTC","updated_at":"Sat, 10 Jun 2023 05:52:45 UTC"}), - JSON.stringify({"id":"abc123xyz456","subscription_id":null,"account":"user123","scope":"project_data","name":"experiment_data_001","did_type":"FILE","state":"PROCESSING","error":null,"rse_expression":"backup_storage","copies":2,"expires_at":null,"weight":null,"locked":false,"locks_ok_cnt":789,"locks_replicating_cnt":1,"locks_stuck_cnt":0,"source_replica_expression":"source_data_center","activity":"Data Processing","grouping":"EXPERIMENT","notification":"YES","stuck_at":null,"purge_replicas":true,"ignore_availability":false,"ignore_account_limit":true,"priority":2,"comments":null,"child_rule_id":null,"eol_at":null,"split_container":true,"meta":null,"created_at":"Tue, 20 Jul 2023 08:45:19 UTC","updated_at":"Wed, 21 Jul 2023 14:20:37 UTC"}) - ].join("\n")), + body: Readable.from( + [ + JSON.stringify({ + id: 'dummy_id', + subscription_id: 'sample_subscription_007', + account: 'dummy_account', + scope: 'dummy_scope', + name: 'dummy_name', + did_type: 'DATASET', + state: 'OK', + error: null, + rse_expression: 'dummy_rse_expression', + copies: 1, + expires_at: null, + weight: null, + locked: true, + locks_ok_cnt: 28635, + locks_replicating_cnt: 0, + locks_stuck_cnt: 0, + source_replica_expression: 'dummy_source_replica_expression', + activity: 'dummy_activity', + grouping: 'DATASET', + notification: 'NO', + stuck_at: null, + purge_replicas: false, + ignore_availability: true, + ignore_account_limit: false, + priority: 3, + comments: null, + child_rule_id: null, + eol_at: null, + split_container: false, + meta: null, + created_at: 'Fri, 09 Jun 2023 13:16:31 UTC', + updated_at: 'Sat, 10 Jun 2023 05:52:45 UTC', + }), + JSON.stringify({ + id: 'abc123xyz456', + subscription_id: null, + account: 'user123', + scope: 'project_data', + name: 'experiment_data_001', + did_type: 'FILE', + state: 'PROCESSING', + error: null, + rse_expression: 'backup_storage', + copies: 2, + expires_at: null, + weight: null, + locked: false, + locks_ok_cnt: 789, + locks_replicating_cnt: 1, + locks_stuck_cnt: 0, + source_replica_expression: 'source_data_center', + activity: 'Data Processing', + grouping: 'EXPERIMENT', + notification: 'YES', + stuck_at: null, + purge_replicas: true, + ignore_availability: false, + ignore_account_limit: true, + priority: 2, + comments: null, + child_rule_id: null, + eol_at: null, + split_container: true, + meta: null, + created_at: 'Tue, 20 Jul 2023 08:45:19 UTC', + updated_at: 'Wed, 21 Jul 2023 14:20:37 UTC', + }), + ].join('\n'), + ), }, }; @@ -32,49 +100,48 @@ describe("DID Gateway List Rules Endpoint Tests", () => { fetchMock.dontMock(); }); it('should successfully stream a list of rules for a DID', async () => { - - const rucioDIDGateway: DIDGatewayOutputPort = appContainer.get(GATEWAYS.DID) - const dto: ListDIDRulesDTO = await rucioDIDGateway.listDIDRules(MockRucioServerFactory.VALID_RUCIO_TOKEN, "test", "dataset1"); + const rucioDIDGateway: DIDGatewayOutputPort = appContainer.get(GATEWAYS.DID); + const dto: ListDIDRulesDTO = await rucioDIDGateway.listDIDRules(MockRucioServerFactory.VALID_RUCIO_TOKEN, 'test', 'dataset1'); expect(dto.status).toBe('success'); - + const rulesStream = dto.stream; expect(rulesStream).toBeDefined(); - if( rulesStream == null || rulesStream == undefined) { + if (rulesStream == null || rulesStream == undefined) { fail('rulesStream is null or undefined'); } - const receivedData: any[] = [] + const receivedData: any[] = []; const onData = (data: DIDRulesDTO) => { - receivedData.push(data) - } + receivedData.push(data); + }; await new Promise((resolve, reject) => { - rulesStream.on('data', onData) - rulesStream.on('end', resolve) - rulesStream.on('error', reject) + rulesStream.on('data', onData); + rulesStream.on('end', resolve); + rulesStream.on('error', reject); }); expect(receivedData.length).toBe(2); expect(receivedData).toEqual([ { - "status": "success", - "id": "dummy_id", - "subscription_id": "sample_subscription_007", - "account": "dummy_account", - "name": "dummy_name", - "state": RuleState.OK, - "last_modified": "Sat, 10 Jun 2023 05:52:45 UTC", + status: 'success', + id: 'dummy_id', + subscription_id: 'sample_subscription_007', + account: 'dummy_account', + name: 'dummy_name', + state: RuleState.OK, + last_modified: 'Sat, 10 Jun 2023 05:52:45 UTC', }, { - "status": "success", - "id": "abc123xyz456", - "subscription_id": undefined, - "account": "user123", - "name": "experiment_data_001", - "state": RuleState.UNKNOWN, - "last_modified": "Wed, 21 Jul 2023 14:20:37 UTC", - } - ]) + status: 'success', + id: 'abc123xyz456', + subscription_id: undefined, + account: 'user123', + name: 'experiment_data_001', + state: RuleState.UNKNOWN, + last_modified: 'Wed, 21 Jul 2023 14:20:37 UTC', + }, + ]); }); -}); \ No newline at end of file +}); diff --git a/test/gateway/did/did-gateway-meta-endpoint.test.ts b/test/gateway/did/did-gateway-meta-endpoint.test.ts index 64f6bad34..af37a6592 100644 --- a/test/gateway/did/did-gateway-meta-endpoint.test.ts +++ b/test/gateway/did/did-gateway-meta-endpoint.test.ts @@ -1,87 +1,87 @@ -import { DIDMetaDTO } from "@/lib/core/dto/did-dto"; -import DIDGatewayOutputPort from "@/lib/core/port/secondary/did-gateway-output-port"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway"; -import MockRucioServerFactory, { MockEndpoint } from "../../fixtures/rucio-server"; +import { DIDMetaDTO } from '@/lib/core/dto/did-dto'; +import DIDGatewayOutputPort from '@/lib/core/port/secondary/did-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import MockRucioServerFactory, { MockEndpoint } from '../../fixtures/rucio-server'; -describe("DID Gateway Meta Endpoint Tests", () => { +describe('DID Gateway Meta Endpoint Tests', () => { beforeEach(() => { fetchMock.doMock(); const didMetaMMockEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/dids/test/dataset1/meta`, - method: "GET", - includes: "test/dataset1/meta", + method: 'GET', + includes: 'test/dataset1/meta', response: { status: 200, headers: { - "Content-Type": "application/json", + 'Content-Type': 'application/json', }, body: JSON.stringify({ - "scope": "test", - "name": "dataset1", - "account": "root", - "did_type": "DATASET", - "is_open": true, - "monotonic": false, - "hidden": false, - "obsolete": false, - "complete": null, - "is_new": true, - "availability": "AVAILABLE", - "suppressed": false, - "bytes": null, - "length": null, - "md5": null, - "adler32": null, - "expired_at": null, - "purge_replicas": true, - "deleted_at": null, - "events": null, - "guid": null, - "project": null, - "datatype": null, - "run_number": null, - "stream_name": null, - "prod_step": null, - "version": null, - "campaign": null, - "task_id": null, - "panda_id": null, - "lumiblocknr": null, - "provenance": null, - "phys_group": null, - "transient": false, - "accessed_at": null, - "closed_at": null, - "eol_at": null, - "is_archive": null, - "constituent": null, - "access_cnt": null, - "created_at": "Mon, 10 Jul 2023 13:23:56 UTC", - "updated_at": "Mon, 10 Jul 2023 13:23:56 UTC" - }) - } - } + scope: 'test', + name: 'dataset1', + account: 'root', + did_type: 'DATASET', + is_open: true, + monotonic: false, + hidden: false, + obsolete: false, + complete: null, + is_new: true, + availability: 'AVAILABLE', + suppressed: false, + bytes: null, + length: null, + md5: null, + adler32: null, + expired_at: null, + purge_replicas: true, + deleted_at: null, + events: null, + guid: null, + project: null, + datatype: null, + run_number: null, + stream_name: null, + prod_step: null, + version: null, + campaign: null, + task_id: null, + panda_id: null, + lumiblocknr: null, + provenance: null, + phys_group: null, + transient: false, + accessed_at: null, + closed_at: null, + eol_at: null, + is_archive: null, + constituent: null, + access_cnt: null, + created_at: 'Mon, 10 Jul 2023 13:23:56 UTC', + updated_at: 'Mon, 10 Jul 2023 13:23:56 UTC', + }), + }, + }; MockRucioServerFactory.createMockRucioServer(true, [didMetaMMockEndpoint]); }); afterEach(() => { fetchMock.dontMock(); }); - it("Should return a DIDMetaDTO", async () => { + it('Should return a DIDMetaDTO', async () => { const didGateway: DIDGatewayOutputPort = appContainer.get(GATEWAYS.DID); - const dto: DIDMetaDTO = await didGateway.getDIDMeta(MockRucioServerFactory.VALID_RUCIO_TOKEN, "test", "dataset1"); - expect(dto.status).toEqual("success") - expect(dto.name).toEqual("dataset1") - expect(dto.scope).toEqual("test") - expect(dto.created_at).toEqual("Mon, 10 Jul 2023 13:23:56 UTC") - }) - - it("Should return an Auth Error", async() => { + const dto: DIDMetaDTO = await didGateway.getDIDMeta(MockRucioServerFactory.VALID_RUCIO_TOKEN, 'test', 'dataset1'); + expect(dto.status).toEqual('success'); + expect(dto.name).toEqual('dataset1'); + expect(dto.scope).toEqual('test'); + expect(dto.created_at).toEqual('Mon, 10 Jul 2023 13:23:56 UTC'); + }); + + it('Should return an Auth Error', async () => { const didGateway: DIDGatewayOutputPort = appContainer.get(GATEWAYS.DID); - const dto: DIDMetaDTO = await didGateway.getDIDMeta("gfhfgsjiyug", "test", "dataset1"); - expect(dto.status).toEqual("error") - expect(dto.errorName).toEqual("Invalid Auth Token") - expect(dto.errorMessage).toEqual("The provided authentication token is invalid or has expired.") - }) -}); \ No newline at end of file + const dto: DIDMetaDTO = await didGateway.getDIDMeta('gfhfgsjiyug', 'test', 'dataset1'); + expect(dto.status).toEqual('error'); + expect(dto.errorName).toEqual('Invalid Auth Token'); + expect(dto.errorMessage).toEqual('The provided authentication token is invalid or has expired.'); + }); +}); diff --git a/test/gateway/did/did-gateway.test.ts b/test/gateway/did/did-gateway.test.ts index 0366af1fd..6e4fa836d 100644 --- a/test/gateway/did/did-gateway.test.ts +++ b/test/gateway/did/did-gateway.test.ts @@ -1,19 +1,19 @@ -import { ListDIDDTO, DIDExtendedDTO } from '@/lib/core/dto/did-dto' -import { DID, DIDType } from '@/lib/core/entity/rucio' -import DIDGatewayOutputPort from '@/lib/core/port/secondary/did-gateway-output-port' -import appContainer from '@/lib/infrastructure/ioc/container-config' -import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway' -import { Readable } from 'stream' +import { ListDIDDTO, DIDExtendedDTO } from '@/lib/core/dto/did-dto'; +import { DID, DIDType } from '@/lib/core/entity/rucio'; +import DIDGatewayOutputPort from '@/lib/core/port/secondary/did-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import { Readable } from 'stream'; describe('DID Gateway Tests', () => { beforeEach(() => { - fetchMock.doMock() + fetchMock.doMock(); fetchMock.mockIf(/^https?:\/\/rucio-host.com.*$/, req => { - const rucioToken = req.headers.get('X-Rucio-Auth-Token') + const rucioToken = req.headers.get('X-Rucio-Auth-Token'); if (rucioToken !== 'rucio-ddmlab-askdjljioj') { return Promise.resolve({ status: 401, - }) + }); } if (req.url.includes('/data17_13TeV/dids/search')) { const stream = Readable.from( @@ -22,77 +22,75 @@ describe('DID Gateway Tests', () => { '"00325748.physics_Main.merge.DAOD_EXOT15.f102_m2608_p3372_tid15339900_01"', '"00325748.physics_Main.merge.DAOD_EXOT15.f102_m2608_p3372_tid15339900_02"', ].join('\n'), - ) + ); return Promise.resolve({ status: 200, headers: { 'Content-Type': 'application/x-json-stream', }, body: stream, - }) + }); } - if (req.url.endsWith('/test/dataset1/status')){ + if (req.url.endsWith('/test/dataset1/status')) { return Promise.resolve({ status: 200, headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ - "scope": "test", - "name": "dataset1", - "type": "DATASET", - "account": "root", - "open": true, - "monotonic": false, - "expired_at": null, - "length": null, - "bytes": null - }) - }) + scope: 'test', + name: 'dataset1', + type: 'DATASET', + account: 'root', + open: true, + monotonic: false, + expired_at: null, + length: null, + bytes: null, + }), + }); } - }) - }) + }); + }); afterEach(() => { - fetchMock.dontMock() - }) + fetchMock.dontMock(); + }); it('should successfully stream DIDs from Newline-Delimitted String to String Array', async () => { - const rucioDIDGateway: DIDGatewayOutputPort = appContainer.get( - GATEWAYS.DID, - ) + const rucioDIDGateway: DIDGatewayOutputPort = appContainer.get(GATEWAYS.DID); const dto: ListDIDDTO = await rucioDIDGateway.listDIDs( 'rucio-ddmlab-askdjljioj', 'data17_13TeV', '00325748.physics_Main.merge.DAOD_EXOT15.f102_m2608_p3372_tid15339900_00', DIDType.DATASET, - ) - expect(dto.status).toBe('success') - expect(dto.stream).not.toBeUndefined() - expect(dto.stream).not.toBeNull() - const didStream = dto.stream + ); + expect(dto.status).toBe('success'); + expect(dto.stream).not.toBeUndefined(); + expect(dto.stream).not.toBeNull(); + const didStream = dto.stream; - if(didStream === null || didStream === undefined){ - fail('didStream is null or undefined') + if (didStream === null || didStream === undefined) { + fail('didStream is null or undefined'); } - const receivedData: DID[] = [] - + const receivedData: DID[] = []; + const onData = (data: any) => { - console.log('data', data) - receivedData.push(data) - } + console.log('data', data); + receivedData.push(data); + }; await new Promise((resolve, reject) => { - didStream.on('data', onData) + didStream.on('data', onData); didStream.on('end', () => { - console.log('end') - didStream.off('data', onData) - resolve() - }) + console.log('end'); + didStream.off('data', onData); + resolve(); + }); didStream.on('error', err => { - didStream.off('data', onData) - reject(err) - }) - }) + didStream.off('data', onData); + reject(err); + }); + }); expect(receivedData).toEqual([ { @@ -110,23 +108,16 @@ describe('DID Gateway Tests', () => { name: '00325748.physics_Main.merge.DAOD_EXOT15.f102_m2608_p3372_tid15339900_02', did_type: 'Dataset', }, - ]) - }) + ]); + }); it("Should fetch DID's status", async () => { - const rucioDIDGateway: DIDGatewayOutputPort = appContainer.get( - GATEWAYS.DID, - ) - const didDTO = await rucioDIDGateway.getDID( - 'rucio-ddmlab-askdjljioj', - 'test', - 'dataset1', - undefined, - ) - expect(didDTO.status).toBe('success') - expect(didDTO.account).toBe('root') - expect(didDTO.open).toBe(true) - expect(didDTO.monotonic).toBe(false) - expect(didDTO.expired_at).toBeNull() - }) -}) + const rucioDIDGateway: DIDGatewayOutputPort = appContainer.get(GATEWAYS.DID); + const didDTO = await rucioDIDGateway.getDID('rucio-ddmlab-askdjljioj', 'test', 'dataset1', undefined); + expect(didDTO.status).toBe('success'); + expect(didDTO.account).toBe('root'); + expect(didDTO.open).toBe(true); + expect(didDTO.monotonic).toBe(false); + expect(didDTO.expired_at).toBeNull(); + }); +}); diff --git a/test/gateway/did/get-did-status.test.ts b/test/gateway/did/get-did-status.test.ts index fea3f8829..271291f05 100644 --- a/test/gateway/did/get-did-status.test.ts +++ b/test/gateway/did/get-did-status.test.ts @@ -1,13 +1,13 @@ -import { DIDExtendedDTO } from "@/lib/core/dto/did-dto" -import { DIDType } from "@/lib/core/entity/rucio" -import DIDGatewayOutputPort from "@/lib/core/port/secondary/did-gateway-output-port" -import appContainer from "@/lib/infrastructure/ioc/container-config" -import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway" -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server" +import { DIDExtendedDTO } from '@/lib/core/dto/did-dto'; +import { DIDType } from '@/lib/core/entity/rucio'; +import DIDGatewayOutputPort from '@/lib/core/port/secondary/did-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; describe('DID Gateway Tests Get STATUS', () => { beforeEach(() => { - fetchMock.doMock() + fetchMock.doMock(); const getDIDStatusEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/dids/test/container/status?dynamic_depth=FILE`, method: 'GET', @@ -18,47 +18,39 @@ describe('DID Gateway Tests Get STATUS', () => { 'Content-Type': 'application/json', }, body: JSON.stringify({ - "scope": "test", - "name": "container", - "type": "CONTAINER", - "account": "root", - "open": true, - "monotonic": false, - "expired_at": null, - "length": 4, - "bytes": 41943040.0 - }) - } - - } + scope: 'test', + name: 'container', + type: 'CONTAINER', + account: 'root', + open: true, + monotonic: false, + expired_at: null, + length: 4, + bytes: 41943040.0, + }), + }, + }; MockRucioServerFactory.createMockRucioServer(true, [getDIDStatusEndpoint]); - }) + }); afterEach(() => { - fetchMock.dontMock() - }) - + fetchMock.dontMock(); + }); + it('should successfully get status of a DID', async () => { - const rucioDIDGateway: DIDGatewayOutputPort = appContainer.get( - GATEWAYS.DID, - ) - const dto: DIDExtendedDTO = await rucioDIDGateway.getDID( - MockRucioServerFactory.VALID_RUCIO_TOKEN, - 'test', - 'container', - DIDType.FILE, - ) + const rucioDIDGateway: DIDGatewayOutputPort = appContainer.get(GATEWAYS.DID); + const dto: DIDExtendedDTO = await rucioDIDGateway.getDID(MockRucioServerFactory.VALID_RUCIO_TOKEN, 'test', 'container', DIDType.FILE); expect(dto).toEqual({ - "status": "success", - "scope": "test", - "name": "container", - "did_type": DIDType.CONTAINER, - "account": "root", - "open": true, - "monotonic": false, - "expired_at": null, - "length": 4, - "bytes": 41943040.0 - }) - }) -}) \ No newline at end of file + status: 'success', + scope: 'test', + name: 'container', + did_type: DIDType.CONTAINER, + account: 'root', + open: true, + monotonic: false, + expired_at: null, + length: 4, + bytes: 41943040.0, + }); + }); +}); diff --git a/test/gateway/env-config-gateway.test.ts b/test/gateway/env-config-gateway.test.ts index 89885f694..6007a28df 100644 --- a/test/gateway/env-config-gateway.test.ts +++ b/test/gateway/env-config-gateway.test.ts @@ -1,266 +1,218 @@ -import { ConfigNotFound, InvalidConfig } from '@/lib/core/exceptions/env-config-exceptions' -import EnvConfigGatewayOutputPort from '@/lib/core/port/secondary/env-config-gateway-output-port' -import appContainer from '@/lib/infrastructure/ioc/container-config' -import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway' -import { createOIDCProviders, deleteOIDCProviders } from 'test/fixtures/oidc-provider-config' - +import { ConfigNotFound, InvalidConfig } from '@/lib/core/exceptions/env-config-exceptions'; +import EnvConfigGatewayOutputPort from '@/lib/core/port/secondary/env-config-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import { createOIDCProviders, deleteOIDCProviders } from 'test/fixtures/oidc-provider-config'; describe('env-config-gateway', () => { it('should return the value of the environment variable', async () => { - const key = 'TEST_ENV_VAR' - const value = 'test-value' - process.env[key] = value - const gateway = appContainer.get( - GATEWAYS.ENV_CONFIG, - ) - const result = await gateway.get(key) - expect(result).toEqual(value) - }) + const key = 'TEST_ENV_VAR'; + const value = 'test-value'; + process.env[key] = value; + const gateway = appContainer.get(GATEWAYS.ENV_CONFIG); + const result = await gateway.get(key); + expect(result).toEqual(value); + }); it('should return undefined if the environment variable does not exist', async () => { - const key = 'TEST_ENV_VAR' - delete process.env[key] - const gateway = appContainer.get( - GATEWAYS.ENV_CONFIG, - ) - const result = await gateway.get(key) - expect(result).toBeUndefined() - }) + const key = 'TEST_ENV_VAR'; + delete process.env[key]; + const gateway = appContainer.get(GATEWAYS.ENV_CONFIG); + const result = await gateway.get(key); + expect(result).toBeUndefined(); + }); it('should return x509 enabled by default', async () => { - const gateway = appContainer.get( - GATEWAYS.ENV_CONFIG, - ) - const result = await gateway.x509Enabled() - expect(result).toBe(true) - }) + const gateway = appContainer.get(GATEWAYS.ENV_CONFIG); + const result = await gateway.x509Enabled(); + expect(result).toBe(true); + }); it('should return x509 enabled if the environment variable is true', async () => { - const key = 'X509_ENABLED' - const value = 'true' - process.env[key] = value - const gateway = appContainer.get( - GATEWAYS.ENV_CONFIG, - ) - const result = await gateway.x509Enabled() - expect(result).toBe(true) - }) + const key = 'X509_ENABLED'; + const value = 'true'; + process.env[key] = value; + const gateway = appContainer.get(GATEWAYS.ENV_CONFIG); + const result = await gateway.x509Enabled(); + expect(result).toBe(true); + }); it('should return x509 disabled if the environment variable is false', async () => { - const key = 'X509_ENABLED' - const value = 'false' - process.env[key] = value - const gateway = appContainer.get( - GATEWAYS.ENV_CONFIG, - ) - const result = await gateway.x509Enabled() - expect(result).toBe(false) - }) -}) + const key = 'X509_ENABLED'; + const value = 'false'; + process.env[key] = value; + const gateway = appContainer.get(GATEWAYS.ENV_CONFIG); + const result = await gateway.x509Enabled(); + expect(result).toBe(false); + }); +}); describe('env-config-gateway oidc config test', () => { beforeEach(() => { - createOIDCProviders() - }) + createOIDCProviders(); + }); afterEach(() => { - deleteOIDCProviders() - }) + deleteOIDCProviders(); + }); it('should return oidc enabled if the environment variable is true', async () => { - const gateway = appContainer.get( - GATEWAYS.ENV_CONFIG, - ) - const result = await gateway.oidcEnabled() - expect(result).toBe(true) - }) + const gateway = appContainer.get(GATEWAYS.ENV_CONFIG); + const result = await gateway.oidcEnabled(); + expect(result).toBe(true); + }); it('should return oidc disabled if the environment variable is false', async () => { - process.env['OIDC_ENABLED'] = 'false' - const gateway = appContainer.get( - GATEWAYS.ENV_CONFIG, - ) - const result = await gateway.oidcEnabled() - expect(result).toBe(false) - }) + process.env['OIDC_ENABLED'] = 'false'; + const gateway = appContainer.get(GATEWAYS.ENV_CONFIG); + const result = await gateway.oidcEnabled(); + expect(result).toBe(false); + }); it('should return oidc providers', async () => { - const gateway = appContainer.get( - GATEWAYS.ENV_CONFIG, - ) - const result = await gateway.oidcProviders() - expect(result.length).toEqual(2) - const cern = result[0] - - expect(cern.name).toEqual('cern') - expect(cern.url).toEqual('https://cern.ch') - expect(cern.iconUrl).toEqual('https://cern.ch/icon.png') - expect(cern.clientId).toEqual('client-id') - expect(cern.clientSecret).toEqual('client-secret') - expect(cern.scopes).toEqual(['scope1', 'scope2']) - expect(cern.authorizationUrl).toEqual('https://cern.ch/auth') - expect(cern.tokenUrl).toEqual('https://cern.ch/token') - expect(cern.userInfoUrl).toEqual('https://cern.ch/userinfo') - expect(cern.redirectUrl).toEqual('https://cern.ch/redirect') - expect(cern.refreshTokenUrl).toEqual('https://cern.ch/userinfo') - }) + const gateway = appContainer.get(GATEWAYS.ENV_CONFIG); + const result = await gateway.oidcProviders(); + expect(result.length).toEqual(2); + const cern = result[0]; + + expect(cern.name).toEqual('cern'); + expect(cern.url).toEqual('https://cern.ch'); + expect(cern.iconUrl).toEqual('https://cern.ch/icon.png'); + expect(cern.clientId).toEqual('client-id'); + expect(cern.clientSecret).toEqual('client-secret'); + expect(cern.scopes).toEqual(['scope1', 'scope2']); + expect(cern.authorizationUrl).toEqual('https://cern.ch/auth'); + expect(cern.tokenUrl).toEqual('https://cern.ch/token'); + expect(cern.userInfoUrl).toEqual('https://cern.ch/userinfo'); + expect(cern.redirectUrl).toEqual('https://cern.ch/redirect'); + expect(cern.refreshTokenUrl).toEqual('https://cern.ch/userinfo'); + }); it('should throw InvalidConfig if oidc is enabled but no providers are provided', async () => { - delete process.env['OIDC_PROVIDERS'] - const gateway = appContainer.get( - GATEWAYS.ENV_CONFIG, - ) - await expect(gateway.oidcProviders()).rejects.toThrow(InvalidConfig) - }) + delete process.env['OIDC_PROVIDERS']; + const gateway = appContainer.get(GATEWAYS.ENV_CONFIG); + await expect(gateway.oidcProviders()).rejects.toThrow(InvalidConfig); + }); it('should NOT throw InvalidConfig if url for OIDC Provider is not provided', async () => { - delete process.env['OIDC_PROVIDER_TEST-PROVIDER_URL'] - const gateway = appContainer.get( - GATEWAYS.ENV_CONFIG, - ) - const result = await gateway.oidcProviders() - expect(result.length).toEqual(2) - const testProvider = result[1] - expect(testProvider.url).toBeUndefined() - }) + delete process.env['OIDC_PROVIDER_TEST-PROVIDER_URL']; + const gateway = appContainer.get(GATEWAYS.ENV_CONFIG); + const result = await gateway.oidcProviders(); + expect(result.length).toEqual(2); + const testProvider = result[1]; + expect(testProvider.url).toBeUndefined(); + }); it('should throw ConfigNotFound if authorization url for OIDC Provider is not provided', async () => { - delete process.env['OIDC_PROVIDER_TEST-PROVIDER_AUTHORIZATION_URL'] - const gateway = appContainer.get( - GATEWAYS.ENV_CONFIG, - ) - await expect(gateway.oidcProviders()).rejects.toThrow(ConfigNotFound) - }) -}) + delete process.env['OIDC_PROVIDER_TEST-PROVIDER_AUTHORIZATION_URL']; + const gateway = appContainer.get(GATEWAYS.ENV_CONFIG); + await expect(gateway.oidcProviders()).rejects.toThrow(ConfigNotFound); + }); +}); describe('env-config-gateway MultiVo Config', () => { beforeEach(() => { - createOIDCProviders() - process.env['MULTIVO_ENABLED'] = 'true' - process.env['VO_LIST'] = 'vo1,vo2' - - process.env['VO_VO1_NAME'] = 'virtual organization 1' - process.env['VO_VO1_LOGO_URL'] = 'https://vo1.ch/logo.png' - process.env['VO_VO1_OIDC_ENABLED'] = 'true' - process.env['VO_VO1_OIDC_PROVIDERS'] = 'cern,test-provider' + createOIDCProviders(); + process.env['MULTIVO_ENABLED'] = 'true'; + process.env['VO_LIST'] = 'vo1,vo2'; - process.env['VO_VO2_NAME'] = 'virtual organization 2' + process.env['VO_VO1_NAME'] = 'virtual organization 1'; + process.env['VO_VO1_LOGO_URL'] = 'https://vo1.ch/logo.png'; + process.env['VO_VO1_OIDC_ENABLED'] = 'true'; + process.env['VO_VO1_OIDC_PROVIDERS'] = 'cern,test-provider'; - }) + process.env['VO_VO2_NAME'] = 'virtual organization 2'; + }); afterEach(() => { - deleteOIDCProviders() - delete process.env['MULTIVO_ENABLED'] - delete process.env['VO_LIST'] - delete process.env['VO_VO1_NAME'] - delete process.env['VO_VO1_LOGO_URL'] - delete process.env['VO_VO1_OIDC_ENABLED'] - delete process.env['VO_VO1_OIDC_PROVIDERS'] - delete process.env['VO_VO2_NAME'] - }) + deleteOIDCProviders(); + delete process.env['MULTIVO_ENABLED']; + delete process.env['VO_LIST']; + delete process.env['VO_VO1_NAME']; + delete process.env['VO_VO1_LOGO_URL']; + delete process.env['VO_VO1_OIDC_ENABLED']; + delete process.env['VO_VO1_OIDC_PROVIDERS']; + delete process.env['VO_VO2_NAME']; + }); it('env-config-gateway should return value of MULTIVO_ENABLED', async () => { - const gateway = appContainer.get( - GATEWAYS.ENV_CONFIG, - ) - const result = await gateway.multiVOEnabled() - expect(result).toEqual(true) + const gateway = appContainer.get(GATEWAYS.ENV_CONFIG); + const result = await gateway.multiVOEnabled(); + expect(result).toEqual(true); // test default value of MULTIVO_ENABLED is false - delete process.env['MULTIVO_ENABLED'] - const result2 = await gateway.multiVOEnabled() - expect(result2).toEqual(false) - }) + delete process.env['MULTIVO_ENABLED']; + const result2 = await gateway.multiVOEnabled(); + expect(result2).toEqual(false); + }); it('should return default vo list if multi_vo is disabled', async () => { - process.env['MULTIVO_ENABLED'] = 'false' - const gateway = appContainer.get( - GATEWAYS.ENV_CONFIG, - ) - const result = await gateway.voList() - expect(result[0].name).toEqual('default') - }) + process.env['MULTIVO_ENABLED'] = 'false'; + const gateway = appContainer.get(GATEWAYS.ENV_CONFIG); + const result = await gateway.voList(); + expect(result[0].name).toEqual('default'); + }); it('should not return default vo if multi_vo is enabled', async () => { - const gateway = appContainer.get( - GATEWAYS.ENV_CONFIG, - ) - const result = await gateway.voList() + const gateway = appContainer.get(GATEWAYS.ENV_CONFIG); + const result = await gateway.voList(); for (const vo of result) { - expect(vo.name).not.toEqual('default') + expect(vo.name).not.toEqual('default'); } - }) + }); it('should return vo list if multi_vo is properly configured', async () => { - const gateway = appContainer.get( - GATEWAYS.ENV_CONFIG, - ) - const result = await gateway.voList() - expect(result.length).toEqual(2) - expect(result[0].name).toEqual('virtual organization 1') - expect(result[0].logoUrl).toEqual('https://vo1.ch/logo.png') - expect(result[0].oidcEnabled).toEqual(true) - expect(result[0].oidcProviders).toHaveLength(2) - - expect(result[1].name).toEqual('virtual organization 2') - expect(result[1].logoUrl).toBeUndefined() - expect(result[1].oidcEnabled).toEqual(false) - expect(result[1].oidcProviders).toHaveLength(0) - }) + const gateway = appContainer.get(GATEWAYS.ENV_CONFIG); + const result = await gateway.voList(); + expect(result.length).toEqual(2); + expect(result[0].name).toEqual('virtual organization 1'); + expect(result[0].logoUrl).toEqual('https://vo1.ch/logo.png'); + expect(result[0].oidcEnabled).toEqual(true); + expect(result[0].oidcProviders).toHaveLength(2); + + expect(result[1].name).toEqual('virtual organization 2'); + expect(result[1].logoUrl).toBeUndefined(); + expect(result[1].oidcEnabled).toEqual(false); + expect(result[1].oidcProviders).toHaveLength(0); + }); it('should throw InvalidConfig if multi_vo is enabled but no vo_list is provided', async () => { - delete process.env['VO_LIST'] - const gateway = appContainer.get( - GATEWAYS.ENV_CONFIG, - ) - await expect(gateway.voList()).rejects.toThrow(InvalidConfig) - }) + delete process.env['VO_LIST']; + const gateway = appContainer.get(GATEWAYS.ENV_CONFIG); + await expect(gateway.voList()).rejects.toThrow(InvalidConfig); + }); it('should throw ConfigNotFound if multi_vo is enabled but no vo_name is provided for any specified vo', async () => { - delete process.env['VO_VO1_NAME'] - const gateway = appContainer.get( - GATEWAYS.ENV_CONFIG, - ) - await expect(gateway.voList()).rejects.toThrow(ConfigNotFound) - }) -}) + delete process.env['VO_VO1_NAME']; + const gateway = appContainer.get(GATEWAYS.ENV_CONFIG); + await expect(gateway.voList()).rejects.toThrow(ConfigNotFound); + }); +}); describe('env-config-gateway Rucio Host config', () => { it('should throw ConfigNotFound if RUCIO_HOST is not provided', async () => { - delete process.env['RUCIO_HOST'] - const gateway = appContainer.get( - GATEWAYS.ENV_CONFIG, - ) - await expect(gateway.rucioHost()).rejects.toThrow(ConfigNotFound) - }) + delete process.env['RUCIO_HOST']; + const gateway = appContainer.get(GATEWAYS.ENV_CONFIG); + await expect(gateway.rucioHost()).rejects.toThrow(ConfigNotFound); + }); it('should return RUCIO_HOST if provided', async () => { - process.env['RUCIO_HOST'] = 'https://rucio.ch' - const gateway = appContainer.get( - GATEWAYS.ENV_CONFIG, - ) - const result = await gateway.rucioHost() - expect(result).toEqual('https://rucio.ch') - delete process.env['RUCIO_HOST'] - }) + process.env['RUCIO_HOST'] = 'https://rucio.ch'; + const gateway = appContainer.get(GATEWAYS.ENV_CONFIG); + const result = await gateway.rucioHost(); + expect(result).toEqual('https://rucio.ch'); + delete process.env['RUCIO_HOST']; + }); it('should throw InvalidConfig if RUCIO_HOST is empty', async () => { - process.env['RUCIO_HOST'] = '' - const gateway = appContainer.get( - GATEWAYS.ENV_CONFIG, - ) - await expect(gateway.rucioHost()).rejects.toThrow(InvalidConfig) - delete process.env['RUCIO_HOST'] - }) + process.env['RUCIO_HOST'] = ''; + const gateway = appContainer.get(GATEWAYS.ENV_CONFIG); + await expect(gateway.rucioHost()).rejects.toThrow(InvalidConfig); + delete process.env['RUCIO_HOST']; + }); it('should throw ConfigNotFound if RUCIO_AUTH_HOST is not provided', async () => { - delete process.env['RUCIO_AUTH_HOST'] - const gateway = appContainer.get( - GATEWAYS.ENV_CONFIG, - ) - await expect(gateway.rucioAuthHost()).rejects.toThrow(ConfigNotFound) - }) + delete process.env['RUCIO_AUTH_HOST']; + const gateway = appContainer.get(GATEWAYS.ENV_CONFIG); + await expect(gateway.rucioAuthHost()).rejects.toThrow(ConfigNotFound); + }); it('should return RUCIO_AUTH_HOST if provided', async () => { - process.env['RUCIO_AUTH_HOST'] = 'https://rucio-auth.ch' - const gateway = appContainer.get( - GATEWAYS.ENV_CONFIG, - ) - const result = await gateway.rucioAuthHost() - expect(result).toEqual('https://rucio-auth.ch') - delete process.env['RUCIO_AUTH_HOST'] - }) + process.env['RUCIO_AUTH_HOST'] = 'https://rucio-auth.ch'; + const gateway = appContainer.get(GATEWAYS.ENV_CONFIG); + const result = await gateway.rucioAuthHost(); + expect(result).toEqual('https://rucio-auth.ch'); + delete process.env['RUCIO_AUTH_HOST']; + }); it('should throw InvalidConfig if RUCIO_AUTH_HOST is empty', async () => { - process.env['RUCIO_AUTH_HOST'] = '' - const gateway = appContainer.get( - GATEWAYS.ENV_CONFIG, - ) - await expect(gateway.rucioAuthHost()).rejects.toThrow(InvalidConfig) - delete process.env['RUCIO_AUTH_HOST'] - }) -}) \ No newline at end of file + process.env['RUCIO_AUTH_HOST'] = ''; + const gateway = appContainer.get(GATEWAYS.ENV_CONFIG); + await expect(gateway.rucioAuthHost()).rejects.toThrow(InvalidConfig); + delete process.env['RUCIO_AUTH_HOST']; + }); +}); diff --git a/test/gateway/jest.gateway.setup.ts b/test/gateway/jest.gateway.setup.ts index b10834a0f..2da620eb4 100644 --- a/test/gateway/jest.gateway.setup.ts +++ b/test/gateway/jest.gateway.setup.ts @@ -1,7 +1,7 @@ -import '@testing-library/jest-dom/extend-expect' -import "reflect-metadata" -import "@inrupt/jest-jsdom-polyfills" -import fetchMock from 'jest-fetch-mock' +import '@testing-library/jest-dom/extend-expect'; +import 'reflect-metadata'; +import '@inrupt/jest-jsdom-polyfills'; +import fetchMock from 'jest-fetch-mock'; // Allow for fetch() mock to handle streams // https://github.com/jefflau/jest-fetch-mock/issues/113#issuecomment-1418504168 @@ -18,4 +18,4 @@ import fetchMock from 'jest-fetch-mock' // value: TempResponse, // }); -fetchMock.enableMocks() \ No newline at end of file +fetchMock.enableMocks(); diff --git a/test/gateway/json-stream.test.ts b/test/gateway/json-stream.test.ts index 90bdf9e46..4d2a8e441 100644 --- a/test/gateway/json-stream.test.ts +++ b/test/gateway/json-stream.test.ts @@ -1,35 +1,35 @@ -import type { HTTPRequest } from '@/lib/sdk/http' -import StreamGatewayOutputPort from '@/lib/core/port/secondary/stream-gateway-output-port' -import appContainer from '@/lib/infrastructure/ioc/container-config' -import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway' -import { PassThrough } from 'node:stream' -import { Response } from 'node-fetch' +import type { HTTPRequest } from '@/lib/sdk/http'; +import StreamGatewayOutputPort from '@/lib/core/port/secondary/stream-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import { PassThrough } from 'node:stream'; +import { Response } from 'node-fetch'; describe('Streaming tests for JSON encoded text payloads', () => { beforeEach(async () => { - fetchMock.mockIf(/^http:\/\/localhost:8080\/.*/, async (req) => { + fetchMock.mockIf(/^http:\/\/localhost:8080\/.*/, async req => { if (req.url.endsWith('textstream') && req.method === 'GET') { - const stream = new PassThrough() - stream.write('Hello') - stream.write('World') - stream.end() + const stream = new PassThrough(); + stream.write('Hello'); + stream.write('World'); + stream.end(); return Promise.resolve({ status: 200, body: stream, - }) + }); } if (req.url.endsWith('goodjsonstream') && req.method === 'GET') { - const stream = new PassThrough() - stream.write('{"Hello":') - stream.write('"World"}') - stream.end() + const stream = new PassThrough(); + stream.write('{"Hello":'); + stream.write('"World"}'); + stream.end(); return Promise.resolve({ status: 200, body: stream, - }) + }); } if (req.url.endsWith('nestedjsonstream') && req.method === 'GET') { - const stream = new PassThrough() + const stream = new PassThrough(); const nestedObject = { parent: { child: { @@ -39,51 +39,51 @@ describe('Streaming tests for JSON encoded text payloads', () => { }, }, }, - } - const json = JSON.stringify(nestedObject) - const chunks = json.match(/.{1,10}/g) || [] + }; + const json = JSON.stringify(nestedObject); + const chunks = json.match(/.{1,10}/g) || []; for (const chunk of chunks) { - stream.write(chunk) + stream.write(chunk); } - stream.end() + stream.end(); return Promise.resolve({ status: 200, body: stream, - }) + }); } - if(req.url.endsWith('listofobjects')) { - const stream = new PassThrough() - const listOfObjects = [] - for(let i = 0; i < 10; i++) { + if (req.url.endsWith('listofobjects')) { + const stream = new PassThrough(); + const listOfObjects = []; + for (let i = 0; i < 10; i++) { listOfObjects.push({ RSE: { name: `RSE${i}`, info: { size: i * 100, - } - } - }) + }, + }, + }); } - const json = JSON.stringify(listOfObjects) + const json = JSON.stringify(listOfObjects); // split the json into chunks of 10 characters - const chunks = json.match(/.{1,20}/g) || [] + const chunks = json.match(/.{1,20}/g) || []; for (const chunk of chunks) { - stream.write(chunk) + stream.write(chunk); } - stream.end() + stream.end(); return Promise.resolve({ status: 200, body: stream, - }) + }); } - }) + }); // uncomment the line below to fetch data directly from a running mock server // fetchMock.dontMock() - }) + }); it('should return the mocked chunks as text', async () => { - const url = 'http://localhost:8080/textstream' - const streamingGateway = appContainer.get(GATEWAYS.STREAM) + const url = 'http://localhost:8080/textstream'; + const streamingGateway = appContainer.get(GATEWAYS.STREAM); const request: HTTPRequest = { url: url, method: 'GET', @@ -91,34 +91,34 @@ describe('Streaming tests for JSON encoded text payloads', () => { headers: { 'Content-Type': 'text/plain', }, - } - const textStream: PassThrough | Response = await streamingGateway.getTextStream(request) - expect(textStream).not.toBeNull() + }; + const textStream: PassThrough | Response = await streamingGateway.getTextStream(request); + expect(textStream).not.toBeNull(); // if response is null fail the test - if(textStream === null) { - fail('response is null') + if (textStream === null) { + fail('response is null'); } - if(textStream instanceof Response) { - fail('response is not a stream') + if (textStream instanceof Response) { + fail('response is not a stream'); } - let chunks:string[] = [] - const outputStream = new PassThrough() - textStream.pipe(outputStream) + let chunks: string[] = []; + const outputStream = new PassThrough(); + textStream.pipe(outputStream); - outputStream.on('data', (chunk) => { - chunks.push(chunk.toString()) - }) + outputStream.on('data', chunk => { + chunks.push(chunk.toString()); + }); outputStream.on('end', () => { - expect(chunks).toEqual(['Hello', 'World']) - }) - while(outputStream.readableLength > 0) { - await new Promise(resolve => setTimeout(resolve, 1000)) + expect(chunks).toEqual(['Hello', 'World']); + }); + while (outputStream.readableLength > 0) { + await new Promise(resolve => setTimeout(resolve, 1000)); } - }) + }); it('should return the mocked chunks as JSON object', async () => { - const url = 'http://localhost:8080/goodjsonstream' - const streamingGateway = appContainer.get(GATEWAYS.STREAM) + const url = 'http://localhost:8080/goodjsonstream'; + const streamingGateway = appContainer.get(GATEWAYS.STREAM); const request: HTTPRequest = { url: url, method: 'GET', @@ -126,39 +126,39 @@ describe('Streaming tests for JSON encoded text payloads', () => { headers: { 'Content-Type': 'application/x-json-stream', }, - } - const {type, content} = await streamingGateway.getJSONChunks(request) - const jsonStream: PassThrough | Response = content - expect(jsonStream).not.toBeNull() + }; + const { type, content } = await streamingGateway.getJSONChunks(request); + const jsonStream: PassThrough | Response = content; + expect(jsonStream).not.toBeNull(); // if response is null fail the test - if(jsonStream === null) { - fail('response is null') + if (jsonStream === null) { + fail('response is null'); } - if(jsonStream instanceof Response) { - fail('response is not a stream') + if (jsonStream instanceof Response) { + fail('response is not a stream'); } - let chunks: any[] = [] - const outputStream = new PassThrough() - jsonStream.pipe(outputStream) + let chunks: any[] = []; + const outputStream = new PassThrough(); + jsonStream.pipe(outputStream); - outputStream.on('data', (chunk) => { - const data = chunk.toString() - const jsonObject = JSON.parse(data) - chunks.push(jsonObject) - }) + outputStream.on('data', chunk => { + const data = chunk.toString(); + const jsonObject = JSON.parse(data); + chunks.push(jsonObject); + }); outputStream.on('end', () => { - expect('Hello' in chunks[0]).toEqual(true) - expect(chunks[0].Hello).toEqual('World') - }) + expect('Hello' in chunks[0]).toEqual(true); + expect(chunks[0].Hello).toEqual('World'); + }); - while(outputStream.readableLength > 0) { - await new Promise(resolve => setTimeout(resolve, 1000)) + while (outputStream.readableLength > 0) { + await new Promise(resolve => setTimeout(resolve, 1000)); } - }) + }); it('should return nested json responses as JSON', async () => { - const url = 'http://localhost:8080/nestedjsonstream' - const streamingGateway = appContainer.get(GATEWAYS.STREAM) + const url = 'http://localhost:8080/nestedjsonstream'; + const streamingGateway = appContainer.get(GATEWAYS.STREAM); const request: HTTPRequest = { url: url, method: 'GET', @@ -166,29 +166,29 @@ describe('Streaming tests for JSON encoded text payloads', () => { headers: { 'Content-Type': 'application/x-json-stream', }, - } - const {type, content} = await streamingGateway.getJSONChunks(request) - const jsonStream: PassThrough | Response = content - expect(jsonStream).not.toBeNull() + }; + const { type, content } = await streamingGateway.getJSONChunks(request); + const jsonStream: PassThrough | Response = content; + expect(jsonStream).not.toBeNull(); // if response is null fail the test - if(jsonStream === null) { - fail('response is null') + if (jsonStream === null) { + fail('response is null'); } - if(jsonStream instanceof Response) { - fail('response is not a stream') + if (jsonStream instanceof Response) { + fail('response is not a stream'); } - let chunks: Object[] = [] - const outputStream = new PassThrough() - jsonStream.pipe(outputStream) + let chunks: Object[] = []; + const outputStream = new PassThrough(); + jsonStream.pipe(outputStream); - outputStream.on('data', (chunk) => { - const data = chunk.toString() - const jsonObject = JSON.parse(data) - chunks.push(jsonObject) - }) + outputStream.on('data', chunk => { + const data = chunk.toString(); + const jsonObject = JSON.parse(data); + chunks.push(jsonObject); + }); outputStream.on('end', () => { - expect(chunks.length).toEqual(1) - const json = chunks[0] + expect(chunks.length).toEqual(1); + const json = chunks[0]; expect(json).toEqual({ parent: { child: { @@ -198,61 +198,61 @@ describe('Streaming tests for JSON encoded text payloads', () => { }, }, }, - }) - }) - while(outputStream.readableLength > 0) { - await new Promise(resolve => setTimeout(resolve, 1000)) + }); + }); + while (outputStream.readableLength > 0) { + await new Promise(resolve => setTimeout(resolve, 1000)); } - }) + }); it('should return list of objects as JSON', async () => { - const url = 'http://localhost:8080/listofobjects' - const streamingGateway = appContainer.get(GATEWAYS.STREAM) + const url = 'http://localhost:8080/listofobjects'; + const streamingGateway = appContainer.get(GATEWAYS.STREAM); const request: HTTPRequest = { url: url, method: 'GET', body: null, headers: {}, - } - const {type, content} = await streamingGateway.getJSONChunks(request) - const jsonStream: PassThrough | Response = content - - expect(jsonStream).not.toBeNull() + }; + const { type, content } = await streamingGateway.getJSONChunks(request); + const jsonStream: PassThrough | Response = content; + + expect(jsonStream).not.toBeNull(); // if response is null fail the test - if(jsonStream === null) { - fail('response is null') + if (jsonStream === null) { + fail('response is null'); } - if(jsonStream instanceof Response) { - fail('response is not a stream') + if (jsonStream instanceof Response) { + fail('response is not a stream'); } - let chunks:Object[] = [] - const outputStream = new PassThrough() - jsonStream.pipe(outputStream) + let chunks: Object[] = []; + const outputStream = new PassThrough(); + jsonStream.pipe(outputStream); outputStream.on('data', (chunk: string) => { - const data = chunk.toString() - const jsonObject = JSON.parse(data) - chunks.push(jsonObject) - }) + const data = chunk.toString(); + const jsonObject = JSON.parse(data); + chunks.push(jsonObject); + }); outputStream.on('end', () => { - const json = chunks - expect(json.length).toEqual(10) + const json = chunks; + expect(json.length).toEqual(10); expect(json[0]).toEqual({ RSE: { name: 'RSE0', info: { size: 0, }, - } - }) + }, + }); expect(json[9]).toEqual({ RSE: { name: 'RSE9', info: { size: 900, }, - } - }) - }) - }) -}) + }, + }); + }); + }); +}); diff --git a/test/gateway/replica/replica-gateway-list-dataset-replicas.test.ts b/test/gateway/replica/replica-gateway-list-dataset-replicas.test.ts index 65c03280e..65b806ec6 100644 --- a/test/gateway/replica/replica-gateway-list-dataset-replicas.test.ts +++ b/test/gateway/replica/replica-gateway-list-dataset-replicas.test.ts @@ -1,14 +1,14 @@ -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server" -import { Readable } from "stream" -import ReplicaGatewayOutputPort from "@/lib/core/port/secondary/replica-gateway-output-port" -import appContainer from "@/lib/infrastructure/ioc/container-config" -import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway" -import { DatasetReplicasDTO, ListReplicasDTO } from "@/lib/core/dto/replica-dto" -import { ReplicaState } from "@/lib/core/entity/rucio" +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; +import { Readable } from 'stream'; +import ReplicaGatewayOutputPort from '@/lib/core/port/secondary/replica-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import { DatasetReplicasDTO, ListReplicasDTO } from '@/lib/core/dto/replica-dto'; +import { ReplicaState } from '@/lib/core/entity/rucio'; describe('Replica Gateway: List Dataset Replicas', () => { beforeEach(() => { - fetchMock.doMock() + fetchMock.doMock(); const listDatasetReplicasEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/replicas/test/dataset1/datasets`, method: 'GET', @@ -21,66 +21,64 @@ describe('Replica Gateway: List Dataset Replicas', () => { body: Readable.from( [ JSON.stringify({ - "scope": "test", - "name": "dataset1", - "rse": "XRD3", - "rse_id": "28e77f4f2c864f7d949eb602d6f05985", - "bytes": 0, - "length": 0, - "available_bytes": 1000, - "available_length": 10, - "state": "UNAVAILABLE", - "created_at": "Tue, 12 Sep 2023 09:12:11 UTC", - "updated_at": "Tue, 12 Sep 2023 09:12:11 UTC", - "accessed_at": null - }), - ].join('\n') - ) - } - } - MockRucioServerFactory.createMockRucioServer(true, [listDatasetReplicasEndpoint]) - }) + scope: 'test', + name: 'dataset1', + rse: 'XRD3', + rse_id: '28e77f4f2c864f7d949eb602d6f05985', + bytes: 0, + length: 0, + available_bytes: 1000, + available_length: 10, + state: 'UNAVAILABLE', + created_at: 'Tue, 12 Sep 2023 09:12:11 UTC', + updated_at: 'Tue, 12 Sep 2023 09:12:11 UTC', + accessed_at: null, + }), + ].join('\n'), + ), + }, + }; + MockRucioServerFactory.createMockRucioServer(true, [listDatasetReplicasEndpoint]); + }); afterEach(() => { - fetchMock.resetMocks() - }) + fetchMock.resetMocks(); + }); it('should successfully stream a list of dataset replicas', async () => { - const rucioReplicaGateway: ReplicaGatewayOutputPort = appContainer.get(GATEWAYS.REPLICA) - const dto: ListReplicasDTO = await rucioReplicaGateway.listDatasetReplicas(MockRucioServerFactory.VALID_RUCIO_TOKEN, 'test', 'dataset1') - expect(dto.status).toBe('success') - - const datasetReplicasStream = dto.stream - expect(datasetReplicasStream).toBeDefined() + const rucioReplicaGateway: ReplicaGatewayOutputPort = appContainer.get(GATEWAYS.REPLICA); + const dto: ListReplicasDTO = await rucioReplicaGateway.listDatasetReplicas(MockRucioServerFactory.VALID_RUCIO_TOKEN, 'test', 'dataset1'); + expect(dto.status).toBe('success'); + + const datasetReplicasStream = dto.stream; + expect(datasetReplicasStream).toBeDefined(); - if(datasetReplicasStream == null || datasetReplicasStream == undefined) { - fail('datasetReplicasStream is null or undefined') + if (datasetReplicasStream == null || datasetReplicasStream == undefined) { + fail('datasetReplicasStream is null or undefined'); } - const receivedData: any[] = [] + const receivedData: any[] = []; const onData = (data: any) => { - receivedData.push(data) - } + receivedData.push(data); + }; await new Promise((resolve, reject) => { - datasetReplicasStream.on('data', onData) - datasetReplicasStream.on('end', resolve) - datasetReplicasStream.on('error', reject) - } - ) + datasetReplicasStream.on('data', onData); + datasetReplicasStream.on('end', resolve); + datasetReplicasStream.on('error', reject); + }); - expect(receivedData.length).toBe(1) + expect(receivedData.length).toBe(1); expect(receivedData).toEqual([ { - "status": "success", - "rse": "XRD3", - "availability": false, - "available_files": 10, - "available_bytes": 1000, - "creation_date": "Tue, 12 Sep 2023 09:12:11 UTC", - "last_accessed": '', - - } as DatasetReplicasDTO - ]) - }) -}) \ No newline at end of file + status: 'success', + rse: 'XRD3', + availability: false, + available_files: 10, + available_bytes: 1000, + creation_date: 'Tue, 12 Sep 2023 09:12:11 UTC', + last_accessed: '', + } as DatasetReplicasDTO, + ]); + }); +}); diff --git a/test/gateway/replica/replica-gateway-list-file-replicas.test.ts b/test/gateway/replica/replica-gateway-list-file-replicas.test.ts index 1e39ae635..4699b0c3d 100644 --- a/test/gateway/replica/replica-gateway-list-file-replicas.test.ts +++ b/test/gateway/replica/replica-gateway-list-file-replicas.test.ts @@ -1,14 +1,14 @@ -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server" -import { Readable } from "stream" -import ReplicaGatewayOutputPort from "@/lib/core/port/secondary/replica-gateway-output-port" -import appContainer from "@/lib/infrastructure/ioc/container-config" -import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway" -import { ListReplicasDTO } from "@/lib/core/dto/replica-dto" -import { ReplicaState } from "@/lib/core/entity/rucio" +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; +import { Readable } from 'stream'; +import ReplicaGatewayOutputPort from '@/lib/core/port/secondary/replica-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import { ListReplicasDTO } from '@/lib/core/dto/replica-dto'; +import { ReplicaState } from '@/lib/core/entity/rucio'; describe('Replica Gateway: List File Replicas', () => { beforeEach(() => { - fetchMock.doMock() + fetchMock.doMock(); const listFileReplicasEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/replicas/list`, method: 'POST', @@ -21,68 +21,63 @@ describe('Replica Gateway: List File Replicas', () => { body: Readable.from( [ JSON.stringify({ - "scope": "test", - "name": "file1", - "rses": { - "XRD3": [ - "root://xrd3:1096//rucio/test/80/25/file1" - ], - "XRD1": [ - "root://xrd1:1094//rucio/test/80/25/file1" - ] + scope: 'test', + name: 'file1', + rses: { + XRD3: ['root://xrd3:1096//rucio/test/80/25/file1'], + XRD1: ['root://xrd1:1094//rucio/test/80/25/file1'], + }, + states: { + XRD3: 'COPYING', + XRD1: 'AVAILABLE', }, - "states": { - "XRD3": "COPYING", - "XRD1": "AVAILABLE" - } }), - ].join('\n') - ) - } - } - MockRucioServerFactory.createMockRucioServer(true, [listFileReplicasEndpoint]) - }) + ].join('\n'), + ), + }, + }; + MockRucioServerFactory.createMockRucioServer(true, [listFileReplicasEndpoint]); + }); afterEach(() => { - fetchMock.resetMocks() - }) + fetchMock.resetMocks(); + }); it('should successfully stream a list of file replicas', async () => { - const rucioReplicaGateway: ReplicaGatewayOutputPort = appContainer.get(GATEWAYS.REPLICA) - const dto: ListReplicasDTO = await rucioReplicaGateway.listFileReplicas(MockRucioServerFactory.VALID_RUCIO_TOKEN, 'test', 'file1') - expect(dto.status).toBe('success') - - const fileReplicasStream = dto.stream - expect(fileReplicasStream).toBeDefined() + const rucioReplicaGateway: ReplicaGatewayOutputPort = appContainer.get(GATEWAYS.REPLICA); + const dto: ListReplicasDTO = await rucioReplicaGateway.listFileReplicas(MockRucioServerFactory.VALID_RUCIO_TOKEN, 'test', 'file1'); + expect(dto.status).toBe('success'); + + const fileReplicasStream = dto.stream; + expect(fileReplicasStream).toBeDefined(); - if(fileReplicasStream == null || fileReplicasStream == undefined) { - fail('fileReplicasStream is null or undefined') + if (fileReplicasStream == null || fileReplicasStream == undefined) { + fail('fileReplicasStream is null or undefined'); } - const receivedData: any[] = [] + const receivedData: any[] = []; const onData = (data: any) => { - receivedData.push(data) - } + receivedData.push(data); + }; await new Promise((resolve, reject) => { - fileReplicasStream.on('data', onData) - fileReplicasStream.on('end', resolve) - fileReplicasStream.on('error', reject) - } - ) + fileReplicasStream.on('data', onData); + fileReplicasStream.on('end', resolve); + fileReplicasStream.on('error', reject); + }); - expect(receivedData.length).toBe(2) + expect(receivedData.length).toBe(2); expect(receivedData).toEqual([ { - "status": "success", - "rse": "XRD3", - "state": ReplicaState.COPYING, + status: 'success', + rse: 'XRD3', + state: ReplicaState.COPYING, }, { - "status": "success", - "rse": "XRD1", - "state": ReplicaState.AVAILABLE, - } - ]) - }) -}) \ No newline at end of file + status: 'success', + rse: 'XRD1', + state: ReplicaState.AVAILABLE, + }, + ]); + }); +}); diff --git a/test/gateway/rse/rse-gateway-get-rse-attributes.test.ts b/test/gateway/rse/rse-gateway-get-rse-attributes.test.ts index aabfe03f8..2c5d7a76b 100644 --- a/test/gateway/rse/rse-gateway-get-rse-attributes.test.ts +++ b/test/gateway/rse/rse-gateway-get-rse-attributes.test.ts @@ -1,7 +1,7 @@ -import RSEGatewayOutputPort from "@/lib/core/port/secondary/rse-gateway-output-port"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway"; -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; +import RSEGatewayOutputPort from '@/lib/core/port/secondary/rse-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; describe('RSEGateway GET RSE Attributes Endpoint Tests', () => { beforeEach(() => { @@ -16,55 +16,54 @@ describe('RSEGateway GET RSE Attributes Endpoint Tests', () => { 'Content-Type': 'application/json', }, body: JSON.stringify({ - "ISP": "CERN- LHC", - "MOCK3": true, - "continent": "EU", - "country_name": "Switzerland", - "region_code": "07", - "time_zone": "Europe/Zurich" - }) - } - } + ISP: 'CERN- LHC', + MOCK3: true, + continent: 'EU', + country_name: 'Switzerland', + region_code: '07', + time_zone: 'Europe/Zurich', + }), + }, + }; MockRucioServerFactory.createMockRucioServer(true, [getRSEAttributesMockEndpoint]); - }) + }); afterEach(() => { fetchMock.dontMock(); - }) + }); test('it should get RSE attributes', async () => { - const rseGateway: RSEGatewayOutputPort = appContainer.get(GATEWAYS.RSE) - const rseAttributesDTO = await rseGateway.getRSEAttributes(MockRucioServerFactory.VALID_RUCIO_TOKEN, 'MOCK3') + const rseGateway: RSEGatewayOutputPort = appContainer.get(GATEWAYS.RSE); + const rseAttributesDTO = await rseGateway.getRSEAttributes(MockRucioServerFactory.VALID_RUCIO_TOKEN, 'MOCK3'); expect(rseAttributesDTO).toEqual({ status: 'success', attributes: [ { - key: 'ISP', - value: 'CERN- LHC' + key: 'ISP', + value: 'CERN- LHC', }, { - key: 'MOCK3', - value: true + key: 'MOCK3', + value: true, }, { - key: 'continent', - value: 'EU' + key: 'continent', + value: 'EU', }, { - key: 'country_name', - value: 'Switzerland' + key: 'country_name', + value: 'Switzerland', }, { - key: 'region_code', - value: '07' + key: 'region_code', + value: '07', }, { - key: 'time_zone', - value: 'Europe/Zurich' - } - ] - - }) - }) -}) \ No newline at end of file + key: 'time_zone', + value: 'Europe/Zurich', + }, + ], + }); + }); +}); diff --git a/test/gateway/rse/rse-gateway-get-rse-protocols.test.ts b/test/gateway/rse/rse-gateway-get-rse-protocols.test.ts index 93374fab2..462479dbf 100644 --- a/test/gateway/rse/rse-gateway-get-rse-protocols.test.ts +++ b/test/gateway/rse/rse-gateway-get-rse-protocols.test.ts @@ -1,8 +1,8 @@ -import { RSEProtocolDTO } from "@/lib/core/dto/rse-dto"; -import RSEGatewayOutputPort from "@/lib/core/port/secondary/rse-gateway-output-port"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway"; -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; +import { RSEProtocolDTO } from '@/lib/core/dto/rse-dto'; +import RSEGatewayOutputPort from '@/lib/core/port/secondary/rse-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; describe('RSEGateway GET RSE Protocols Endpoint Tests', () => { beforeEach(() => { @@ -18,156 +18,154 @@ describe('RSEGateway GET RSE Protocols Endpoint Tests', () => { }, body: JSON.stringify([ { - "domains": { - "lan": { - "delete": 1, - "read": 1, - "write": 1 + domains: { + lan: { + delete: 1, + read: 1, + write: 1, + }, + wan: { + delete: 1, + read: 1, + third_party_copy_read: 0, + third_party_copy_write: 0, + write: 1, + }, }, - "wan": { - "delete": 1, - "read": 1, - "third_party_copy_read": 0, - "third_party_copy_write": 0, - "write": 1 - } - }, - "extended_attributes": { - "space_token": "ATLASDATATAPE", - "web_service_path": "/srm/managerv2?SFN=" - }, - "hostname": "localhost", - "impl": "rucio.rse.protocols.posix.Default", - "port": 0, - "prefix": "/tmp/rucio_rse/", - "scheme": "file" + extended_attributes: { + space_token: 'ATLASDATATAPE', + web_service_path: '/srm/managerv2?SFN=', + }, + hostname: 'localhost', + impl: 'rucio.rse.protocols.posix.Default', + port: 0, + prefix: '/tmp/rucio_rse/', + scheme: 'file', }, { - "domains": { - "lan": { - "delete": 1, - "read": 1, - "write": 1 + domains: { + lan: { + delete: 1, + read: 1, + write: 1, + }, + wan: { + delete: 1, + read: 1, + third_party_copy_read: 0, + third_party_copy_write: 0, + write: 1, + }, }, - "wan": { - "delete": 1, - "read": 1, - "third_party_copy_read": 0, - "third_party_copy_write": 0, - "write": 1 - } - }, - "extended_attributes": null, - "hostname": "mock3.com", - "impl": "rucio.rse.protocols.webdav.Default", - "port": 2880, - "prefix": "/pnfs/rucio/disk-only/scratchdisk/", - "scheme": "https" + extended_attributes: null, + hostname: 'mock3.com', + impl: 'rucio.rse.protocols.webdav.Default', + port: 2880, + prefix: '/pnfs/rucio/disk-only/scratchdisk/', + scheme: 'https', }, { - "domains": { - "lan": { - "delete": 1, - "read": 1, - "write": 1 + domains: { + lan: { + delete: 1, + read: 1, + write: 1, + }, + wan: { + delete: 1, + read: 1, + third_party_copy_read: 1, + third_party_copy_write: 1, + write: 1, + }, + }, + extended_attributes: { + space_token: 'RUCIODISK', + web_service_path: '/srm/managerv2?SFN=', }, - "wan": { - "delete": 1, - "read": 1, - "third_party_copy_read": 1, - "third_party_copy_write": 1, - "write": 1 - } - }, - "extended_attributes": { - "space_token": "RUCIODISK", - "web_service_path": "/srm/managerv2?SFN=" - }, - "hostname": "mock3.com", - "impl": "rucio.rse.protocols.srm.Default", - "port": 8443, - "prefix": "/rucio/tmpdisk/rucio_tests/", - "scheme": "srm" - } - ]) - } - } + hostname: 'mock3.com', + impl: 'rucio.rse.protocols.srm.Default', + port: 8443, + prefix: '/rucio/tmpdisk/rucio_tests/', + scheme: 'srm', + }, + ]), + }, + }; MockRucioServerFactory.createMockRucioServer(true, [getRSEProtocolsMockEndpoint]); - }) + }); test('it should get RSE protocols', async () => { - const rseGateway: RSEGatewayOutputPort = appContainer.get(GATEWAYS.RSE) - const rseProtocolDTO: RSEProtocolDTO = await rseGateway.getRSEProtocols(MockRucioServerFactory.VALID_RUCIO_TOKEN, 'MOCK3') - expect(rseProtocolDTO).toBeDefined() - expect(rseProtocolDTO.status).toEqual('success') + const rseGateway: RSEGatewayOutputPort = appContainer.get(GATEWAYS.RSE); + const rseProtocolDTO: RSEProtocolDTO = await rseGateway.getRSEProtocols(MockRucioServerFactory.VALID_RUCIO_TOKEN, 'MOCK3'); + expect(rseProtocolDTO).toBeDefined(); + expect(rseProtocolDTO.status).toEqual('success'); expect(rseProtocolDTO.protocols).toEqual([ { - "rseid": "MOCK3", - "scheme": "file", - "hostname": "localhost", - "port": 0, - "prefix": "/tmp/rucio_rse/", - "impl": "rucio.rse.protocols.posix.Default", - "priorities_lan": { - "read": 1, - "write": 1, - "delete": 1 - }, - "priorities_wan": { - "read": 1, - "write": 1, - "delete": 1, - "tpcread": 0, - "tpcwrite": 0 - }, + rseid: 'MOCK3', + scheme: 'file', + hostname: 'localhost', + port: 0, + prefix: '/tmp/rucio_rse/', + impl: 'rucio.rse.protocols.posix.Default', + priorities_lan: { + read: 1, + write: 1, + delete: 1, + }, + priorities_wan: { + read: 1, + write: 1, + delete: 1, + tpcread: 0, + tpcwrite: 0, + }, }, { - "rseid": "MOCK3", - "scheme": "https", - "hostname": "mock3.com", - "port": 2880, - "prefix": "/pnfs/rucio/disk-only/scratchdisk/", - "impl": "rucio.rse.protocols.webdav.Default", - "priorities_lan": { - "read": 1, - "write": 1, - "delete": 1 - }, - "priorities_wan": { - "read": 1, - "write": 1, - "delete": 1, - "tpcread": 0, - "tpcwrite": 0 - }, + rseid: 'MOCK3', + scheme: 'https', + hostname: 'mock3.com', + port: 2880, + prefix: '/pnfs/rucio/disk-only/scratchdisk/', + impl: 'rucio.rse.protocols.webdav.Default', + priorities_lan: { + read: 1, + write: 1, + delete: 1, + }, + priorities_wan: { + read: 1, + write: 1, + delete: 1, + tpcread: 0, + tpcwrite: 0, + }, }, { - "rseid": "MOCK3", - "scheme": "srm", - "hostname": "mock3.com", - "port": 8443, - "prefix": "/rucio/tmpdisk/rucio_tests/", - "impl": "rucio.rse.protocols.srm.Default", - "priorities_lan": { - "read": 1, - "write": 1, - "delete": 1 - }, - "priorities_wan": { - "read": 1, - "write": 1, - "delete": 1, - "tpcread": 1, - "tpcwrite": 1 - }, - } - ]) - + rseid: 'MOCK3', + scheme: 'srm', + hostname: 'mock3.com', + port: 8443, + prefix: '/rucio/tmpdisk/rucio_tests/', + impl: 'rucio.rse.protocols.srm.Default', + priorities_lan: { + read: 1, + write: 1, + delete: 1, + }, + priorities_wan: { + read: 1, + write: 1, + delete: 1, + tpcread: 1, + tpcwrite: 1, + }, + }, + ]); + }); - }) - afterEach(() => { fetchMock.dontMock(); - }) -}) \ No newline at end of file + }); +}); diff --git a/test/gateway/rse/rse-gateway-get-rse.test.ts b/test/gateway/rse/rse-gateway-get-rse.test.ts index 12b65a024..a0236b10c 100644 --- a/test/gateway/rse/rse-gateway-get-rse.test.ts +++ b/test/gateway/rse/rse-gateway-get-rse.test.ts @@ -1,9 +1,9 @@ -import { ListRSEsDTO, RSEDTO } from "@/lib/core/dto/rse-dto"; -import { RSEType } from "@/lib/core/entity/rucio"; -import RSEGatewayOutputPort from "@/lib/core/port/secondary/rse-gateway-output-port"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway"; -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; +import { ListRSEsDTO, RSEDTO } from '@/lib/core/dto/rse-dto'; +import { RSEType } from '@/lib/core/entity/rucio'; +import RSEGatewayOutputPort from '@/lib/core/port/secondary/rse-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; describe('RSEGateway Get', () => { beforeEach(() => { @@ -15,7 +15,7 @@ describe('RSEGateway Get', () => { volatile: false, deterministic: true, staging_area: false, - } + }; const listRSEsEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/rses/DINGDONGRSE`, @@ -26,22 +26,22 @@ describe('RSEGateway Get', () => { headers: { 'Content-Type': 'application/json', }, - body: JSON.stringify(rse) - } - } + body: JSON.stringify(rse), + }, + }; MockRucioServerFactory.createMockRucioServer(true, [listRSEsEndpoint]); - }) + }); afterEach(() => { fetchMock.dontMock(); - }) + }); it('should fetch a single RSE', async () => { - const rseGateway: RSEGatewayOutputPort = appContainer.get(GATEWAYS.RSE) - const getRSEDTO: RSEDTO = await rseGateway.getRSE( MockRucioServerFactory.VALID_RUCIO_TOKEN, 'DINGDONGRSE') - expect(getRSEDTO.status).toEqual('success') - expect(getRSEDTO.id).toEqual('abcd') - expect(getRSEDTO.name).toEqual('DINGDONGRSE') - expect(getRSEDTO.rse_type).toEqual(RSEType.DISK) - expect(getRSEDTO.volatile).toEqual(false) - }) -}) \ No newline at end of file + const rseGateway: RSEGatewayOutputPort = appContainer.get(GATEWAYS.RSE); + const getRSEDTO: RSEDTO = await rseGateway.getRSE(MockRucioServerFactory.VALID_RUCIO_TOKEN, 'DINGDONGRSE'); + expect(getRSEDTO.status).toEqual('success'); + expect(getRSEDTO.id).toEqual('abcd'); + expect(getRSEDTO.name).toEqual('DINGDONGRSE'); + expect(getRSEDTO.rse_type).toEqual(RSEType.DISK); + expect(getRSEDTO.volatile).toEqual(false); + }); +}); diff --git a/test/gateway/rse/rse-gateway-list-rses.test.ts b/test/gateway/rse/rse-gateway-list-rses.test.ts index e459304a5..0fa6a0da3 100644 --- a/test/gateway/rse/rse-gateway-list-rses.test.ts +++ b/test/gateway/rse/rse-gateway-list-rses.test.ts @@ -1,20 +1,100 @@ -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; -import { Readable } from "stream"; -import RSEGatewayOutputPort from "@/lib/core/port/secondary/rse-gateway-output-port"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway"; -import { ListRSEsDTO, RSEDTO } from "@/lib/core/dto/rse-dto"; -import { collectStreamedData } from "test/fixtures/stream-test-utils"; -import { RSEType } from "@/lib/core/entity/rucio"; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; +import { Readable } from 'stream'; +import RSEGatewayOutputPort from '@/lib/core/port/secondary/rse-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import { ListRSEsDTO, RSEDTO } from '@/lib/core/dto/rse-dto'; +import { collectStreamedData } from 'test/fixtures/stream-test-utils'; +import { RSEType } from '@/lib/core/entity/rucio'; describe('RSEGateway', () => { beforeEach(() => { fetchMock.doMock(); - const rseStream = Readable.from([ - JSON.stringify({"id": "ANONYMOUS_ID_1", "rse": "ANONYMOUS_RSE_1", "vo": "def", "rse_type": "DISK", "deterministic": true, "volatile": false, "staging_area": false, "city": null, "region_code": null, "country_name": null, "continent": null, "time_zone": null, "ISP": null, "ASN": null, "longitude": null, "latitude": null, "availability": 7, "availability_read": true, "availability_write": true, "availability_delete": true, "qos_class": null, "deleted": false, "deleted_at": null, "created_at": "Thu, 03 Aug 2023 11:37:48 UTC", "updated_at": "Thu, 03 Aug 2023 11:37:48 UTC"}), - JSON.stringify({"id": "ANONYMOUS_ID_2", "rse": "ANONYMOUS_RSE_2", "vo": "def", "rse_type": "DISK", "deterministic": true, "volatile": false, "staging_area": false, "city": null, "region_code": null, "country_name": null, "continent": null, "time_zone": null, "ISP": null, "ASN": null, "longitude": null, "latitude": null, "availability": 7, "availability_read": true, "availability_write": true, "availability_delete": true, "qos_class": null, "deleted": false, "deleted_at": null, "created_at": "Thu, 03 Aug 2023 11:37:48 UTC", "updated_at": "Thu, 03 Aug 2023 11:37:48 UTC"}), - JSON.stringify({"id": "ANONYMOUS_ID_3", "rse": "ANONYMOUS_RSE_3", "vo": "def", "rse_type": "DISK", "deterministic": true, "volatile": false, "staging_area": false, "city": null, "region_code": null, "country_name": null, "continent": null, "time_zone": null, "ISP": null, "ASN": null, "longitude": null, "latitude": null, "availability": 7, "availability_read": true, "availability_write": true, "availability_delete": true, "qos_class": null, "deleted": false, "deleted_at": null, "created_at": "Thu, 03 Aug 2023 11:37:48 UTC", "updated_at": "Thu, 03 Aug 2023 11:37:48 UTC"}), - ].join('\n')) + const rseStream = Readable.from( + [ + JSON.stringify({ + id: 'ANONYMOUS_ID_1', + rse: 'ANONYMOUS_RSE_1', + vo: 'def', + rse_type: 'DISK', + deterministic: true, + volatile: false, + staging_area: false, + city: null, + region_code: null, + country_name: null, + continent: null, + time_zone: null, + ISP: null, + ASN: null, + longitude: null, + latitude: null, + availability: 7, + availability_read: true, + availability_write: true, + availability_delete: true, + qos_class: null, + deleted: false, + deleted_at: null, + created_at: 'Thu, 03 Aug 2023 11:37:48 UTC', + updated_at: 'Thu, 03 Aug 2023 11:37:48 UTC', + }), + JSON.stringify({ + id: 'ANONYMOUS_ID_2', + rse: 'ANONYMOUS_RSE_2', + vo: 'def', + rse_type: 'DISK', + deterministic: true, + volatile: false, + staging_area: false, + city: null, + region_code: null, + country_name: null, + continent: null, + time_zone: null, + ISP: null, + ASN: null, + longitude: null, + latitude: null, + availability: 7, + availability_read: true, + availability_write: true, + availability_delete: true, + qos_class: null, + deleted: false, + deleted_at: null, + created_at: 'Thu, 03 Aug 2023 11:37:48 UTC', + updated_at: 'Thu, 03 Aug 2023 11:37:48 UTC', + }), + JSON.stringify({ + id: 'ANONYMOUS_ID_3', + rse: 'ANONYMOUS_RSE_3', + vo: 'def', + rse_type: 'DISK', + deterministic: true, + volatile: false, + staging_area: false, + city: null, + region_code: null, + country_name: null, + continent: null, + time_zone: null, + ISP: null, + ASN: null, + longitude: null, + latitude: null, + availability: 7, + availability_read: true, + availability_write: true, + availability_delete: true, + qos_class: null, + deleted: false, + deleted_at: null, + created_at: 'Thu, 03 Aug 2023 11:37:48 UTC', + updated_at: 'Thu, 03 Aug 2023 11:37:48 UTC', + }), + ].join('\n'), + ); const listRSEsEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/rses`, @@ -25,38 +105,37 @@ describe('RSEGateway', () => { headers: { 'Content-Type': 'application/x-json-stream', }, - body: rseStream - } - } + body: rseStream, + }, + }; MockRucioServerFactory.createMockRucioServer(true, [listRSEsEndpoint]); - }) + }); afterEach(() => { fetchMock.dontMock(); - }) + }); it('Should fetch a list of RSEs', async () => { - const rseGateway: RSEGatewayOutputPort = appContainer.get(GATEWAYS.RSE) - const listRSEsDTO: ListRSEsDTO = await rseGateway.listRSEs( MockRucioServerFactory.VALID_RUCIO_TOKEN, 'def') - expect(listRSEsDTO.status).toEqual('success') + const rseGateway: RSEGatewayOutputPort = appContainer.get(GATEWAYS.RSE); + const listRSEsDTO: ListRSEsDTO = await rseGateway.listRSEs(MockRucioServerFactory.VALID_RUCIO_TOKEN, 'def'); + expect(listRSEsDTO.status).toEqual('success'); - const rseStream = listRSEsDTO.stream - if( rseStream == null || rseStream == undefined) { - fail('RSE stream is null or undefined') + const rseStream = listRSEsDTO.stream; + if (rseStream == null || rseStream == undefined) { + fail('RSE stream is null or undefined'); } - const recievedData: RSEDTO[] = await collectStreamedData(rseStream) - expect(recievedData.length).toEqual(3) - expect(recievedData[0].id).toEqual('ANONYMOUS_ID_1') - expect(recievedData[0].name).toEqual('ANONYMOUS_RSE_1') - expect(recievedData[0].rse_type).toEqual(RSEType.DISK) - - }) + const recievedData: RSEDTO[] = await collectStreamedData(rseStream); + expect(recievedData.length).toEqual(3); + expect(recievedData[0].id).toEqual('ANONYMOUS_ID_1'); + expect(recievedData[0].name).toEqual('ANONYMOUS_RSE_1'); + expect(recievedData[0].rse_type).toEqual(RSEType.DISK); + }); it('Should fail with Auth Error without returning a stream', async () => { - const rseGateway: RSEGatewayOutputPort = appContainer.get(GATEWAYS.RSE) - const listRSEsDTO: ListRSEsDTO = await rseGateway.listRSEs( 'bad rucio auth token', 'def') - expect(listRSEsDTO.status).toEqual('error') - expect(listRSEsDTO.stream).toEqual(undefined) - expect(listRSEsDTO.errorCode).toEqual(401) - expect(listRSEsDTO.errorMessage).toEqual('The provided authentication token is invalid or has expired.') - }) -}); \ No newline at end of file + const rseGateway: RSEGatewayOutputPort = appContainer.get(GATEWAYS.RSE); + const listRSEsDTO: ListRSEsDTO = await rseGateway.listRSEs('bad rucio auth token', 'def'); + expect(listRSEsDTO.status).toEqual('error'); + expect(listRSEsDTO.stream).toEqual(undefined); + expect(listRSEsDTO.errorCode).toEqual(401); + expect(listRSEsDTO.errorMessage).toEqual('The provided authentication token is invalid or has expired.'); + }); +}); diff --git a/test/gateway/rule/rule-gateway-get-rule.test.ts b/test/gateway/rule/rule-gateway-get-rule.test.ts index 5d601ba03..92b3b0631 100644 --- a/test/gateway/rule/rule-gateway-get-rule.test.ts +++ b/test/gateway/rule/rule-gateway-get-rule.test.ts @@ -1,15 +1,14 @@ -import { RuleDTO, RuleReplicaLockStateDTO } from "@/lib/core/dto/rule-dto"; -import { LockState, RuleState } from "@/lib/core/entity/rucio"; -import RuleGatewayOutputPort from "@/lib/core/port/secondary/rule-gateway-output-port"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway"; -import { BaseStreamableDTO } from "@/lib/sdk/dto"; -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; -import { collectStreamedData } from "test/fixtures/stream-test-utils"; -import { Readable } from "stream"; +import { RuleDTO, RuleReplicaLockStateDTO } from '@/lib/core/dto/rule-dto'; +import { LockState, RuleState } from '@/lib/core/entity/rucio'; +import RuleGatewayOutputPort from '@/lib/core/port/secondary/rule-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import { BaseStreamableDTO } from '@/lib/sdk/dto'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; +import { collectStreamedData } from 'test/fixtures/stream-test-utils'; +import { Readable } from 'stream'; - -describe("Rule Gateway", () => { +describe('Rule Gateway', () => { beforeEach(() => { fetchMock.doMock(); const getRuleEndpoint: MockEndpoint = { @@ -22,76 +21,76 @@ describe("Rule Gateway", () => { 'Content-Type': 'application/x-json-stream', }, body: JSON.stringify({ - "error": null, - "locks_stuck_cnt": 0, - "ignore_availability": false, - "meta": null, - "subscription_id": null, - "rse_expression": "XRD3", - "source_replica_expression": null, - "ignore_account_limit": false, - "created_at": "Mon, 27 Nov 2023 17:57:44 UTC", - "account": "root", - "copies": 1, - "activity": "User Subscriptions", - "priority": 3, - "updated_at": "Mon, 27 Nov 2023 17:57:44 UTC", - "scope": "test", - "expires_at": null, - "grouping": "DATASET", - "name": "container", - "weight": null, - "notification": "NO", - "comments": null, - "did_type": "CONTAINER", - "locked": false, - "stuck_at": null, - "child_rule_id": null, - "state": "REPLICATING", - "locks_ok_cnt": 0, - "purge_replicas": false, - "eol_at": null, - "id": "817b3030097446a38b3b842bf528e112", - "locks_replicating_cnt": 4, - "split_container": false - }) - } - } + error: null, + locks_stuck_cnt: 0, + ignore_availability: false, + meta: null, + subscription_id: null, + rse_expression: 'XRD3', + source_replica_expression: null, + ignore_account_limit: false, + created_at: 'Mon, 27 Nov 2023 17:57:44 UTC', + account: 'root', + copies: 1, + activity: 'User Subscriptions', + priority: 3, + updated_at: 'Mon, 27 Nov 2023 17:57:44 UTC', + scope: 'test', + expires_at: null, + grouping: 'DATASET', + name: 'container', + weight: null, + notification: 'NO', + comments: null, + did_type: 'CONTAINER', + locked: false, + stuck_at: null, + child_rule_id: null, + state: 'REPLICATING', + locks_ok_cnt: 0, + purge_replicas: false, + eol_at: null, + id: '817b3030097446a38b3b842bf528e112', + locks_replicating_cnt: 4, + split_container: false, + }), + }, + }; const replicaLockStates = [ JSON.stringify({ - "scope": "test", - "name": "file1", - "rse_id": "c8b8113ddcdb4ec78e0846171e594280", - "rse": "XRD3", - "state": "REPLICATING", - "rule_id": "817b3030097446a38b3b842bf528e112" + scope: 'test', + name: 'file1', + rse_id: 'c8b8113ddcdb4ec78e0846171e594280', + rse: 'XRD3', + state: 'REPLICATING', + rule_id: '817b3030097446a38b3b842bf528e112', }), JSON.stringify({ - "scope": "test", - "name": "file2", - "rse_id": "c8b8113ddcdb4ec78e0846171e594280", - "rse": "XRD3", - "state": "REPLICATING", - "rule_id": "817b3030097446a38b3b842bf528e112" + scope: 'test', + name: 'file2', + rse_id: 'c8b8113ddcdb4ec78e0846171e594280', + rse: 'XRD3', + state: 'REPLICATING', + rule_id: '817b3030097446a38b3b842bf528e112', }), JSON.stringify({ - "scope": "test", - "name": "file3", - "rse_id": "c8b8113ddcdb4ec78e0846171e594280", - "rse": "XRD3", - "state": "REPLICATING", - "rule_id": "817b3030097446a38b3b842bf528e112" + scope: 'test', + name: 'file3', + rse_id: 'c8b8113ddcdb4ec78e0846171e594280', + rse: 'XRD3', + state: 'REPLICATING', + rule_id: '817b3030097446a38b3b842bf528e112', }), JSON.stringify({ - "scope": "test", - "name": "file4", - "rse_id": "c8b8113ddcdb4ec78e0846171e594280", - "rse": "XRD3", - "state": "REPLICATING", - "rule_id": "817b3030097446a38b3b842bf528e112" - }) - ] + scope: 'test', + name: 'file4', + rse_id: 'c8b8113ddcdb4ec78e0846171e594280', + rse: 'XRD3', + state: 'REPLICATING', + rule_id: '817b3030097446a38b3b842bf528e112', + }), + ]; const listRuleReplicaLocksEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/rules/817b3030097446a38b3b842bf528e112/locks`, @@ -102,23 +101,25 @@ describe("Rule Gateway", () => { headers: { 'Content-Type': 'application/x-json-stream', }, - body: Readable.from(replicaLockStates.join('\n')) - } - - } + body: Readable.from(replicaLockStates.join('\n')), + }, + }; MockRucioServerFactory.createMockRucioServer(true, [getRuleEndpoint, listRuleReplicaLocksEndpoint]); }); afterEach(() => { fetchMock.dontMock(); }); - it("Should fetch details of a rule", async () => { + it('Should fetch details of a rule', async () => { const ruleGateway: RuleGatewayOutputPort = appContainer.get(GATEWAYS.RULE); - const listRuleLockStatesDTO: BaseStreamableDTO = await ruleGateway.listRuleReplicaLockStates(MockRucioServerFactory.VALID_RUCIO_TOKEN, '817b3030097446a38b3b842bf528e112'); + const listRuleLockStatesDTO: BaseStreamableDTO = await ruleGateway.listRuleReplicaLockStates( + MockRucioServerFactory.VALID_RUCIO_TOKEN, + '817b3030097446a38b3b842bf528e112', + ); expect(listRuleLockStatesDTO.status).toEqual('success'); const ruleStream = listRuleLockStatesDTO.stream; - if(ruleStream == null || ruleStream == undefined) { + if (ruleStream == null || ruleStream == undefined) { fail('Rule stream is null or undefined'); } @@ -126,6 +127,5 @@ describe("Rule Gateway", () => { expect(recievedData.length).toEqual(4); expect(recievedData[0].name).toEqual('file1'); expect(recievedData[0].state).toEqual(LockState.REPLICATING); - }); -}) \ No newline at end of file +}); diff --git a/test/gateway/rule/rule-gateway-list-rule-replica-lock-states.test.ts b/test/gateway/rule/rule-gateway-list-rule-replica-lock-states.test.ts index 2d25fc92b..f6ec6d3db 100644 --- a/test/gateway/rule/rule-gateway-list-rule-replica-lock-states.test.ts +++ b/test/gateway/rule/rule-gateway-list-rule-replica-lock-states.test.ts @@ -1,49 +1,48 @@ -import { RuleReplicaLockStateDTO } from "@/lib/core/dto/rule-dto"; -import RuleGatewayOutputPort from "@/lib/core/port/secondary/rule-gateway-output-port"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway"; -import { Readable } from "stream"; -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; -import { collectStreamedData } from "test/fixtures/stream-test-utils"; +import { RuleReplicaLockStateDTO } from '@/lib/core/dto/rule-dto'; +import RuleGatewayOutputPort from '@/lib/core/port/secondary/rule-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import { Readable } from 'stream'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; +import { collectStreamedData } from 'test/fixtures/stream-test-utils'; - -describe("RuleGateway", () => { +describe('RuleGateway', () => { beforeEach(() => { fetchMock.doMock(); const ruleReplicaLockStateStream = Readable.from([ JSON.stringify({ - "scope": "test", - "name": "file1", - "rse_id": "e815ec46bfa2427cac191cc36ac94527", - "rse": "XRD3", - "state": "REPLICATING", - "rule_id": "0dcdc93fab714f8b84bad116c409483b" + scope: 'test', + name: 'file1', + rse_id: 'e815ec46bfa2427cac191cc36ac94527', + rse: 'XRD3', + state: 'REPLICATING', + rule_id: '0dcdc93fab714f8b84bad116c409483b', }) + '\n', JSON.stringify({ - "scope": "test", - "name": "file2", - "rse_id": "e815ec46bfa2427cac191cc36ac94527", - "rse": "XRD3", - "state": "REPLICATING", - "rule_id": "0dcdc93fab714f8b84bad116c409483b" + scope: 'test', + name: 'file2', + rse_id: 'e815ec46bfa2427cac191cc36ac94527', + rse: 'XRD3', + state: 'REPLICATING', + rule_id: '0dcdc93fab714f8b84bad116c409483b', }) + '\n', JSON.stringify({ - "scope": "test", - "name": "file3", - "rse_id": "e815ec46bfa2427cac191cc36ac94527", - "rse": "XRD3", - "state": "REPLICATING", - "rule_id": "0dcdc93fab714f8b84bad116c409483b" + scope: 'test', + name: 'file3', + rse_id: 'e815ec46bfa2427cac191cc36ac94527', + rse: 'XRD3', + state: 'REPLICATING', + rule_id: '0dcdc93fab714f8b84bad116c409483b', }) + '\n', JSON.stringify({ - "scope": "test", - "name": "file4", - "rse_id": "e815ec46bfa2427cac191cc36ac94527", - "rse": "XRD3", - "state": "REPLICATING", - "rule_id": "0dcdc93fab714f8b84bad116c409483b" - }) + '\n' - ]) + scope: 'test', + name: 'file4', + rse_id: 'e815ec46bfa2427cac191cc36ac94527', + rse: 'XRD3', + state: 'REPLICATING', + rule_id: '0dcdc93fab714f8b84bad116c409483b', + }) + '\n', + ]); const listRuleReplicaLockStatesEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/rules/0dcdc93fab714f8b84bad116c409483b/locks`, @@ -54,9 +53,9 @@ describe("RuleGateway", () => { headers: { 'Content-Type': 'application/x-json-stream', }, - body: ruleReplicaLockStateStream - } - } + body: ruleReplicaLockStateStream, + }, + }; MockRucioServerFactory.createMockRucioServer(true, [listRuleReplicaLockStatesEndpoint]); }); @@ -65,13 +64,16 @@ describe("RuleGateway", () => { fetchMock.dontMock(); }); - it("Should fetch a list of rule replica lock states", async () => { + it('Should fetch a list of rule replica lock states', async () => { const ruleGateway: RuleGatewayOutputPort = appContainer.get(GATEWAYS.RULE); - const listRuleReplicaLockStatesDTO = await ruleGateway.listRuleReplicaLockStates(MockRucioServerFactory.VALID_RUCIO_TOKEN, '0dcdc93fab714f8b84bad116c409483b'); + const listRuleReplicaLockStatesDTO = await ruleGateway.listRuleReplicaLockStates( + MockRucioServerFactory.VALID_RUCIO_TOKEN, + '0dcdc93fab714f8b84bad116c409483b', + ); expect(listRuleReplicaLockStatesDTO.status).toEqual('success'); const ruleReplicaLockStateStream = listRuleReplicaLockStatesDTO.stream; - if(ruleReplicaLockStateStream == null || ruleReplicaLockStateStream == undefined) { + if (ruleReplicaLockStateStream == null || ruleReplicaLockStateStream == undefined) { fail('Rule replica lock state stream is null or undefined'); } @@ -80,4 +82,4 @@ describe("RuleGateway", () => { expect(recievedData[0].rse).toEqual('XRD3'); expect(recievedData[0].name).toEqual('file1'); }); -}); \ No newline at end of file +}); diff --git a/test/gateway/rule/rule-gateway-list-rules-for-account.test.ts b/test/gateway/rule/rule-gateway-list-rules-for-account.test.ts index 0bf82cbb7..231227c3b 100644 --- a/test/gateway/rule/rule-gateway-list-rules-for-account.test.ts +++ b/test/gateway/rule/rule-gateway-list-rules-for-account.test.ts @@ -1,20 +1,123 @@ -import { RuleDTO } from "@/lib/core/dto/rule-dto"; -import RuleGatewayOutputPort from "@/lib/core/port/secondary/rule-gateway-output-port"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway"; -import { Readable } from "stream"; -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; -import { collectStreamedData } from "test/fixtures/stream-test-utils"; +import { RuleDTO } from '@/lib/core/dto/rule-dto'; +import RuleGatewayOutputPort from '@/lib/core/port/secondary/rule-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import { Readable } from 'stream'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; +import { collectStreamedData } from 'test/fixtures/stream-test-utils'; - -describe("RuleGateway", () => { +describe('RuleGateway', () => { beforeEach(() => { fetchMock.doMock(); - const ruleStream = Readable.from([ - JSON.stringify({"error": null, "locks_stuck_cnt": 0, "ignore_availability": false, "meta": null, "subscription_id": null, "rse_expression": "XRD1", "source_replica_expression": null, "ignore_account_limit": false, "created_at": "Mon, 27 Nov 2023 17:55:34 UTC", "account": "root", "copies": 1, "activity": "User Subscriptions", "priority": 3, "updated_at": "Mon, 27 Nov 2023 17:56:00 UTC", "scope": "test", "expires_at": null, "grouping": "DATASET", "name": "file1", "weight": null, "notification": "NO", "comments": null, "did_type": "FILE", "locked": false, "stuck_at": null, "child_rule_id": null, "state": "OK", "locks_ok_cnt": 1, "purge_replicas": false, "eol_at": null, "id": "e456aa5c7ae04c1cbd6c1bf9c9e6621d", "locks_replicating_cnt": 0, "split_container": false, "bytes": 10485760}), - JSON.stringify({"error": null, "locks_stuck_cnt": 0, "ignore_availability": false, "meta": null, "subscription_id": null, "rse_expression": "XRD1", "source_replica_expression": null, "ignore_account_limit": false, "created_at": "Mon, 27 Nov 2023 17:56:03 UTC", "account": "root", "copies": 1, "activity": "User Subscriptions", "priority": 3, "updated_at": "Mon, 27 Nov 2023 17:56:29 UTC", "scope": "test", "expires_at": null, "grouping": "DATASET", "name": "file2", "weight": null, "notification": "NO", "comments": null, "did_type": "FILE", "locked": false, "stuck_at": null, "child_rule_id": null, "state": "OK", "locks_ok_cnt": 1, "purge_replicas": false, "eol_at": null, "id": "f6339c0ab1814ee289ecfdb5e8011909", "locks_replicating_cnt": 0, "split_container": false, "bytes": 10485760}), - JSON.stringify({"error": null, "locks_stuck_cnt": 0, "ignore_availability": false, "meta": null, "subscription_id": null, "rse_expression": "XRD2", "source_replica_expression": null, "ignore_account_limit": false, "created_at": "Mon, 27 Nov 2023 17:56:32 UTC", "account": "root", "copies": 1, "activity": "User Subscriptions", "priority": 3, "updated_at": "Mon, 27 Nov 2023 17:56:58 UTC", "scope": "test", "expires_at": null, "grouping": "DATASET", "name": "file3", "weight": null, "notification": "NO", "comments": null, "did_type": "FILE", "locked": false, "stuck_at": null, "child_rule_id": null, "state": "OK", "locks_ok_cnt": 1, "purge_replicas": false, "eol_at": null, "id": "5242276fa0314af495d57c13a1a1a990", "locks_replicating_cnt": 0, "split_container": false, "bytes": 10485760}), - ].join('\n')); + const ruleStream = Readable.from( + [ + JSON.stringify({ + error: null, + locks_stuck_cnt: 0, + ignore_availability: false, + meta: null, + subscription_id: null, + rse_expression: 'XRD1', + source_replica_expression: null, + ignore_account_limit: false, + created_at: 'Mon, 27 Nov 2023 17:55:34 UTC', + account: 'root', + copies: 1, + activity: 'User Subscriptions', + priority: 3, + updated_at: 'Mon, 27 Nov 2023 17:56:00 UTC', + scope: 'test', + expires_at: null, + grouping: 'DATASET', + name: 'file1', + weight: null, + notification: 'NO', + comments: null, + did_type: 'FILE', + locked: false, + stuck_at: null, + child_rule_id: null, + state: 'OK', + locks_ok_cnt: 1, + purge_replicas: false, + eol_at: null, + id: 'e456aa5c7ae04c1cbd6c1bf9c9e6621d', + locks_replicating_cnt: 0, + split_container: false, + bytes: 10485760, + }), + JSON.stringify({ + error: null, + locks_stuck_cnt: 0, + ignore_availability: false, + meta: null, + subscription_id: null, + rse_expression: 'XRD1', + source_replica_expression: null, + ignore_account_limit: false, + created_at: 'Mon, 27 Nov 2023 17:56:03 UTC', + account: 'root', + copies: 1, + activity: 'User Subscriptions', + priority: 3, + updated_at: 'Mon, 27 Nov 2023 17:56:29 UTC', + scope: 'test', + expires_at: null, + grouping: 'DATASET', + name: 'file2', + weight: null, + notification: 'NO', + comments: null, + did_type: 'FILE', + locked: false, + stuck_at: null, + child_rule_id: null, + state: 'OK', + locks_ok_cnt: 1, + purge_replicas: false, + eol_at: null, + id: 'f6339c0ab1814ee289ecfdb5e8011909', + locks_replicating_cnt: 0, + split_container: false, + bytes: 10485760, + }), + JSON.stringify({ + error: null, + locks_stuck_cnt: 0, + ignore_availability: false, + meta: null, + subscription_id: null, + rse_expression: 'XRD2', + source_replica_expression: null, + ignore_account_limit: false, + created_at: 'Mon, 27 Nov 2023 17:56:32 UTC', + account: 'root', + copies: 1, + activity: 'User Subscriptions', + priority: 3, + updated_at: 'Mon, 27 Nov 2023 17:56:58 UTC', + scope: 'test', + expires_at: null, + grouping: 'DATASET', + name: 'file3', + weight: null, + notification: 'NO', + comments: null, + did_type: 'FILE', + locked: false, + stuck_at: null, + child_rule_id: null, + state: 'OK', + locks_ok_cnt: 1, + purge_replicas: false, + eol_at: null, + id: '5242276fa0314af495d57c13a1a1a990', + locks_replicating_cnt: 0, + split_container: false, + bytes: 10485760, + }), + ].join('\n'), + ); const listRulesEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/rules`, @@ -25,9 +128,9 @@ describe("RuleGateway", () => { headers: { 'Content-Type': 'application/x-json-stream', }, - body: ruleStream - } - } + body: ruleStream, + }, + }; MockRucioServerFactory.createMockRucioServer(true, [listRulesEndpoint]); }); @@ -36,13 +139,13 @@ describe("RuleGateway", () => { fetchMock.dontMock(); }); - it("Should fetch a list of rules", async () => { + it('Should fetch a list of rules', async () => { const ruleGateway: RuleGatewayOutputPort = appContainer.get(GATEWAYS.RULE); const listRulesDTO = await ruleGateway.listRules(MockRucioServerFactory.VALID_RUCIO_TOKEN); expect(listRulesDTO.status).toEqual('success'); const ruleStream = listRulesDTO.stream; - if(ruleStream == null || ruleStream == undefined) { + if (ruleStream == null || ruleStream == undefined) { fail('Rule stream is null or undefined'); } @@ -50,7 +153,5 @@ describe("RuleGateway", () => { expect(recievedData.length).toEqual(3); expect(recievedData[0].id).toEqual('e456aa5c7ae04c1cbd6c1bf9c9e6621d'); expect(recievedData[0].name).toEqual('file1'); - }); - -}); \ No newline at end of file +}); diff --git a/test/gateway/subscription/list-subscription-rule-states.test.ts b/test/gateway/subscription/list-subscription-rule-states.test.ts index 8c00a0b57..97689f2da 100644 --- a/test/gateway/subscription/list-subscription-rule-states.test.ts +++ b/test/gateway/subscription/list-subscription-rule-states.test.ts @@ -1,14 +1,14 @@ -import SubscriptionGatewayOutputPort from "@/lib/core/port/secondary/subscription-gateway-output-port" -import appContainer from "@/lib/infrastructure/ioc/container-config" -import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway" -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server" -import { Readable } from "stream" -import { BaseStreamableDTO } from "@/lib/sdk/dto" -import { SubscriptionRuleStateDTO } from "@/lib/core/dto/subscription-dto" +import SubscriptionGatewayOutputPort from '@/lib/core/port/secondary/subscription-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; +import { Readable } from 'stream'; +import { BaseStreamableDTO } from '@/lib/sdk/dto'; +import { SubscriptionRuleStateDTO } from '@/lib/core/dto/subscription-dto'; describe('Get Subscription Rule States', () => { beforeEach(() => { - fetchMock.doMock() + fetchMock.doMock(); const getSubscriptionRuleStatesEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/subscriptions/ddmadmin/*Functional Test/Rules/States`, method: 'GET', @@ -20,71 +20,76 @@ describe('Get Subscription Rule States', () => { }, body: Readable.from( [ - JSON.stringify(["ddmadmin", "EVNT to T0 with 1 year lifetime", "OK", 15464]), - JSON.stringify(["ddmadmin", "group.phys-gener to CERN-PROD_PHYS-GENER", "OK", 5344]), - JSON.stringify(["ddmadmin", "*Functional Test", "OK", 95918]), - JSON.stringify(["ddmadmin", "T0 DESD to T1 tape", "OK", 2382]), - ].join('\n')) - } - } + JSON.stringify(['ddmadmin', 'EVNT to T0 with 1 year lifetime', 'OK', 15464]), + JSON.stringify(['ddmadmin', 'group.phys-gener to CERN-PROD_PHYS-GENER', 'OK', 5344]), + JSON.stringify(['ddmadmin', '*Functional Test', 'OK', 95918]), + JSON.stringify(['ddmadmin', 'T0 DESD to T1 tape', 'OK', 2382]), + ].join('\n'), + ), + }, + }; MockRucioServerFactory.createMockRucioServer(true, [getSubscriptionRuleStatesEndpoint]); - }) + }); afterEach(() => { - fetchMock.dontMock() - }) + fetchMock.dontMock(); + }); - it("Should fetch subscription rule states", async () => { + it('Should fetch subscription rule states', async () => { const subscriptionGateway: SubscriptionGatewayOutputPort = appContainer.get(GATEWAYS.SUBSCRIPTION); - const listSubscriptionRuleStatesDTO: BaseStreamableDTO = await subscriptionGateway.listSubscriptionRuleStates(MockRucioServerFactory.VALID_RUCIO_TOKEN, 'ddmadmin', '*Functional Test'); - expect(listSubscriptionRuleStatesDTO.status).toEqual('success') + const listSubscriptionRuleStatesDTO: BaseStreamableDTO = await subscriptionGateway.listSubscriptionRuleStates( + MockRucioServerFactory.VALID_RUCIO_TOKEN, + 'ddmadmin', + '*Functional Test', + ); + expect(listSubscriptionRuleStatesDTO.status).toEqual('success'); - const subscriptionRuleStatesStream = listSubscriptionRuleStatesDTO.stream + const subscriptionRuleStatesStream = listSubscriptionRuleStatesDTO.stream; - if(subscriptionRuleStatesStream == null || subscriptionRuleStatesStream == undefined) { - fail('Subscription Rule States stream is null or undefined') + if (subscriptionRuleStatesStream == null || subscriptionRuleStatesStream == undefined) { + fail('Subscription Rule States stream is null or undefined'); } - const receivedData: SubscriptionRuleStateDTO[] = [] + const receivedData: SubscriptionRuleStateDTO[] = []; const onData = (data: SubscriptionRuleStateDTO) => { - receivedData.push(data) - } + receivedData.push(data); + }; await new Promise((resolve, reject) => { - subscriptionRuleStatesStream.on('data', onData) - subscriptionRuleStatesStream.on('end', resolve) - subscriptionRuleStatesStream.on('error', reject) + subscriptionRuleStatesStream.on('data', onData); + subscriptionRuleStatesStream.on('end', resolve); + subscriptionRuleStatesStream.on('error', reject); }); expect(receivedData.length).toEqual(4); expect(receivedData).toEqual([ { status: 'success', - account: "ddmadmin", - subscriptionName: "EVNT to T0 with 1 year lifetime", - state: "OK", + account: 'ddmadmin', + subscriptionName: 'EVNT to T0 with 1 year lifetime', + state: 'OK', count: 15464, }, { status: 'success', - account: "ddmadmin", - subscriptionName: "group.phys-gener to CERN-PROD_PHYS-GENER", - state: "OK", + account: 'ddmadmin', + subscriptionName: 'group.phys-gener to CERN-PROD_PHYS-GENER', + state: 'OK', count: 5344, }, { status: 'success', - account: "ddmadmin", - subscriptionName: "*Functional Test", - state: "OK", + account: 'ddmadmin', + subscriptionName: '*Functional Test', + state: 'OK', count: 95918, }, { status: 'success', - account: "ddmadmin", - subscriptionName: "T0 DESD to T1 tape", - state: "OK", + account: 'ddmadmin', + subscriptionName: 'T0 DESD to T1 tape', + state: 'OK', count: 2382, }, ]); @@ -93,19 +98,19 @@ describe('Get Subscription Rule States', () => { const obj1 = { status: 'success', states_ok: 1, - } + }; const obj2 = { status: 'success', states_replicating: 2, - } + }; const mergedObj = { ...obj1, ...obj2, - } + }; expect(mergedObj).toEqual({ status: 'success', states_ok: 1, states_replicating: 2, - }) - }) -}) \ No newline at end of file + }); + }); +}); diff --git a/test/gateway/subscription/subscription-gateway.test.ts b/test/gateway/subscription/subscription-gateway.test.ts index b3b5fe06a..be62662c8 100644 --- a/test/gateway/subscription/subscription-gateway.test.ts +++ b/test/gateway/subscription/subscription-gateway.test.ts @@ -1,11 +1,10 @@ -import { SubscriptionState } from "@/lib/core/entity/rucio"; -import SubscriptionGatewayOutputPort from "@/lib/core/port/secondary/subscription-gateway-output-port"; -import appContainer from "@/lib/infrastructure/ioc/container-config"; -import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway"; -import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; -import { Readable } from "stream"; -import { ListSubscriptionsDTO, SubscriptionDTO } from "@/lib/core/dto/subscription-dto"; - +import { SubscriptionState } from '@/lib/core/entity/rucio'; +import SubscriptionGatewayOutputPort from '@/lib/core/port/secondary/subscription-gateway-output-port'; +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import GATEWAYS from '@/lib/infrastructure/ioc/ioc-symbols-gateway'; +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server'; +import { Readable } from 'stream'; +import { ListSubscriptionsDTO, SubscriptionDTO } from '@/lib/core/dto/subscription-dto'; describe('SubscriptionGateway', () => { beforeEach(() => { @@ -20,24 +19,26 @@ describe('SubscriptionGateway', () => { 'Content-Type': 'application/x-json-stream', }, body: JSON.stringify({ - "id": "bccaabb5877a443abd6c56f3271557df", - "name": "*Functional Test", - "filter": "{\"scope\": [\"tests\"], \"project\": [\"step14\"], \"split_rule\": true}", - "replication_rules": "[{\"activity\": \"Functional Test\", \"rse_expression\": \"tier=1&type=DATADISK\", \"source_replica_expression\": \"CERN-PROD_DATADISK\", \"copies\": \"*\", \"lifetime\": 172800, \"comments\": \"Functional tests from Tier-0 to Tier-1s\"}, {\"activity\": \"Functional Test\", \"rse_expression\": \"tier=2&type=DATADISK\", \"source_replica_expression\": \"tier=1&type=DATADISK\", \"copies\": \"*\", \"lifetime\": 172800, \"comments\": \"Functional tests from Tier-1s to Tier-2s\"}, {\"activity\": \"Functional Test\", \"rse_expression\": \"type=TEST\", \"copies\": \"*\", \"lifetime\": 172800, \"comments\": \"Functional tests to RSEs of type TEST\"}]", - "policyid": 0, - "state": "UPDATED", - "last_processed": "Tue, 18 Jul 2023 12:00:30 UTC", - "account": "ddmadmin", - "lifetime": "Sun, 25 May 2042 15:41:54 UTC", - "comments": "The Automatix daemon is configured to periodically produce small datasets for testing purposes and upload them to CERN-PROD_DATADISK. This subscription creates replication rules from Tier-0 to the Tier-1 DATADISKs, from the Tier-1s to the Tier-2 DATADISKs, and from anywhere to RSEs of type TEST. All created rules and the datasets themselves have a lifetime of 2 days.", - "retroactive": false, - "expired_at": null, - "created_at": "Wed, 21 May 2014 08:40:15 UTC", - "updated_at": "Tue, 18 Jul 2023 12:00:30 UTC" - }) - } - } - + id: 'bccaabb5877a443abd6c56f3271557df', + name: '*Functional Test', + filter: '{"scope": ["tests"], "project": ["step14"], "split_rule": true}', + replication_rules: + '[{"activity": "Functional Test", "rse_expression": "tier=1&type=DATADISK", "source_replica_expression": "CERN-PROD_DATADISK", "copies": "*", "lifetime": 172800, "comments": "Functional tests from Tier-0 to Tier-1s"}, {"activity": "Functional Test", "rse_expression": "tier=2&type=DATADISK", "source_replica_expression": "tier=1&type=DATADISK", "copies": "*", "lifetime": 172800, "comments": "Functional tests from Tier-1s to Tier-2s"}, {"activity": "Functional Test", "rse_expression": "type=TEST", "copies": "*", "lifetime": 172800, "comments": "Functional tests to RSEs of type TEST"}]', + policyid: 0, + state: 'UPDATED', + last_processed: 'Tue, 18 Jul 2023 12:00:30 UTC', + account: 'ddmadmin', + lifetime: 'Sun, 25 May 2042 15:41:54 UTC', + comments: + 'The Automatix daemon is configured to periodically produce small datasets for testing purposes and upload them to CERN-PROD_DATADISK. This subscription creates replication rules from Tier-0 to the Tier-1 DATADISKs, from the Tier-1s to the Tier-2 DATADISKs, and from anywhere to RSEs of type TEST. All created rules and the datasets themselves have a lifetime of 2 days.', + retroactive: false, + expired_at: null, + created_at: 'Wed, 21 May 2014 08:40:15 UTC', + updated_at: 'Tue, 18 Jul 2023 12:00:30 UTC', + }), + }, + }; + const getSubscriptionByIdEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/subscriptions/Id/bngjsrfdtlkhugrdgflgiu`, method: 'GET', @@ -48,31 +49,79 @@ describe('SubscriptionGateway', () => { 'Content-Type': 'application/json', }, body: JSON.stringify({ - "name": "*Sensitive Data", - "filter": "{\"scope\": [\"hidden\"], \"project\": [\"hidden\"], \"split_rule\": true}", - "policyid": 0, - "last_processed": "Mon, 31 Jul 2023 07:33:29 UTC", - "account": "ddmadmin", - "comments": "Sensitive data description has been omitted for privacy reasons.", - "expired_at": null, - "updated_at": "Mon, 31 Jul 2023 07:33:29 UTC", - "id": "bccaabb5877a443abd6c56f3271557df", - "replication_rules": "[{\"activity\": \"Hidden Activity\", \"rse_expression\": \"hidden=1&restricted=true\", \"source_replica_expression\": \"hidden-replica\", \"copies\": \"*\", \"lifetime\": 172800, \"comments\": \"Hidden activity description has been omitted for privacy reasons.\"}]", - "state": "UPDATED", - "lifetime": "Sun, 25 May 2042 15:41:54 UTC", - "retroactive": false, - "created_at": "Wed, 21 May 2014 08:40:15 UTC" - }) - } - } - - - - const subscriptionStream = Readable.from([ - JSON.stringify({"id": "c674f72385a14dc8bb5ceba3e491da5a", "name": "wguan test weight", "filter": "{\"scope\": [\"tests\"]}", "replication_rules": "[{\"rse_expression\": \"INFN-T1_SCRATCHDISK|IN2P3-CC_SCRATCHDISK\", \"copies\": 1, \"weight\": \"stresstestweight\"}]", "policyid": 0, "state": "INACTIVE", "last_processed": "Thu, 17 Jul 2014 07:21:03 UTC", "account": "ddmadmin", "lifetime": "Tue, 01 May 2288 07:21:03 UTC", "comments": null, "retroactive": false, "expired_at": null, "created_at": "Thu, 17 Jul 2014 07:21:04 UTC", "updated_at": "Thu, 17 Jul 2014 07:21:04 UTC"}), - JSON.stringify({"id": "f8fb1e9b69e842daa0e1a29914114593", "name": "Functional test T2", "filter": "{\"project\": [\"step14\"], \"scope\": [\"tests\"], \"split_rule\": true, \"transient\": [\"None\", \"0\"]}", "replication_rules": "[{\"lifetime\": 172800, \"activity\": \"Functional Test\", \"copies\": 20, \"source_replica_expression\": \"tier=1\\\\site=CERN-PROD\", \"rse_expression\": \"(tier=2&type=DATADISK\\\\ruciotestsite=true)\\\\todecommission=true\"}]", "policyid": 0, "state": "INACTIVE", "last_processed": "Thu, 19 May 2022 11:46:11 UTC", "account": "ddmadmin", "lifetime": "Sun, 25 May 2042 15:58:21 UTC", "comments": "Functional tests from T1 to T2", "retroactive": false, "expired_at": null, "created_at": "Mon, 21 Jul 2014 12:18:39 UTC", "updated_at": "Thu, 19 May 2022 11:46:13 UTC"}), - JSON.stringify({"id": "6171d1b00b424e41a3c5c73c4cdb20b5", "name": "T0 AOD to nucleus", "filter": "{\"scope\": [\"data15_13TeV\", \"data15_5TeV\", \"data15_900GeV\", \"data15_comm\", \"data15_cos\", \"data15_hi\", \"data16_13TeV\", \"data16_14TeV\", \"data16_comm\", \"data16_cos\", \"data16_hip5TeV\", \"data16_hip8TeV\", \"data17_13TeV\", \"data17_5TeV\", \"data17_900GeV\", \"data17_comm\", \"data17_cos\", \"data17_hi\", \"data18_13TeV\", \"data18_1beam\", \"data18_1p8TeV\", \"data18_900GeV\", \"data18_calib\", \"data18_comm\", \"data18_cos\", \"data18_hi\", \"data22_13p6TeV\", \"data22_900GeV\", \"data22_comm\", \"data22_cos\", \"data22_hi\", \"data22_idcomm\"], \"datatype\": [\"AOD\"], \"transient\": [\"None\", \"0\"], \"prod_step\": [\"merge\"], \"did_type\": [\"DATASET\"], \"split_rule\": true}", "replication_rules": "[{\"copies\": 1, \"rse_expression\": \"type=DATADISK&datapolicynucleus=true\", \"activity\": \"T0 Export\", \"weight\": \"mouweight\"}]", "policyid": 3, "state": "INACTIVE", "last_processed": "Thu, 28 Jul 2022 09:11:28 UTC", "account": "ddmadmin", "lifetime": "Wed, 27 Jul 2022 09:11:49 UTC", "comments": "T0 AOD to nucleus (permanent)", "retroactive": false, "expired_at": "Thu, 28 Jul 2022 09:12:07 UTC", "created_at": "Fri, 29 May 2015 12:01:44 UTC", "updated_at": "Thu, 28 Jul 2022 09:12:07 UTC"}) - ].join('\n')) + name: '*Sensitive Data', + filter: '{"scope": ["hidden"], "project": ["hidden"], "split_rule": true}', + policyid: 0, + last_processed: 'Mon, 31 Jul 2023 07:33:29 UTC', + account: 'ddmadmin', + comments: 'Sensitive data description has been omitted for privacy reasons.', + expired_at: null, + updated_at: 'Mon, 31 Jul 2023 07:33:29 UTC', + id: 'bccaabb5877a443abd6c56f3271557df', + replication_rules: + '[{"activity": "Hidden Activity", "rse_expression": "hidden=1&restricted=true", "source_replica_expression": "hidden-replica", "copies": "*", "lifetime": 172800, "comments": "Hidden activity description has been omitted for privacy reasons."}]', + state: 'UPDATED', + lifetime: 'Sun, 25 May 2042 15:41:54 UTC', + retroactive: false, + created_at: 'Wed, 21 May 2014 08:40:15 UTC', + }), + }, + }; + + const subscriptionStream = Readable.from( + [ + JSON.stringify({ + id: 'c674f72385a14dc8bb5ceba3e491da5a', + name: 'wguan test weight', + filter: '{"scope": ["tests"]}', + replication_rules: '[{"rse_expression": "INFN-T1_SCRATCHDISK|IN2P3-CC_SCRATCHDISK", "copies": 1, "weight": "stresstestweight"}]', + policyid: 0, + state: 'INACTIVE', + last_processed: 'Thu, 17 Jul 2014 07:21:03 UTC', + account: 'ddmadmin', + lifetime: 'Tue, 01 May 2288 07:21:03 UTC', + comments: null, + retroactive: false, + expired_at: null, + created_at: 'Thu, 17 Jul 2014 07:21:04 UTC', + updated_at: 'Thu, 17 Jul 2014 07:21:04 UTC', + }), + JSON.stringify({ + id: 'f8fb1e9b69e842daa0e1a29914114593', + name: 'Functional test T2', + filter: '{"project": ["step14"], "scope": ["tests"], "split_rule": true, "transient": ["None", "0"]}', + replication_rules: + '[{"lifetime": 172800, "activity": "Functional Test", "copies": 20, "source_replica_expression": "tier=1\\\\site=CERN-PROD", "rse_expression": "(tier=2&type=DATADISK\\\\ruciotestsite=true)\\\\todecommission=true"}]', + policyid: 0, + state: 'INACTIVE', + last_processed: 'Thu, 19 May 2022 11:46:11 UTC', + account: 'ddmadmin', + lifetime: 'Sun, 25 May 2042 15:58:21 UTC', + comments: 'Functional tests from T1 to T2', + retroactive: false, + expired_at: null, + created_at: 'Mon, 21 Jul 2014 12:18:39 UTC', + updated_at: 'Thu, 19 May 2022 11:46:13 UTC', + }), + JSON.stringify({ + id: '6171d1b00b424e41a3c5c73c4cdb20b5', + name: 'T0 AOD to nucleus', + filter: '{"scope": ["data15_13TeV", "data15_5TeV", "data15_900GeV", "data15_comm", "data15_cos", "data15_hi", "data16_13TeV", "data16_14TeV", "data16_comm", "data16_cos", "data16_hip5TeV", "data16_hip8TeV", "data17_13TeV", "data17_5TeV", "data17_900GeV", "data17_comm", "data17_cos", "data17_hi", "data18_13TeV", "data18_1beam", "data18_1p8TeV", "data18_900GeV", "data18_calib", "data18_comm", "data18_cos", "data18_hi", "data22_13p6TeV", "data22_900GeV", "data22_comm", "data22_cos", "data22_hi", "data22_idcomm"], "datatype": ["AOD"], "transient": ["None", "0"], "prod_step": ["merge"], "did_type": ["DATASET"], "split_rule": true}', + replication_rules: + '[{"copies": 1, "rse_expression": "type=DATADISK&datapolicynucleus=true", "activity": "T0 Export", "weight": "mouweight"}]', + policyid: 3, + state: 'INACTIVE', + last_processed: 'Thu, 28 Jul 2022 09:11:28 UTC', + account: 'ddmadmin', + lifetime: 'Wed, 27 Jul 2022 09:11:49 UTC', + comments: 'T0 AOD to nucleus (permanent)', + retroactive: false, + expired_at: 'Thu, 28 Jul 2022 09:12:07 UTC', + created_at: 'Fri, 29 May 2015 12:01:44 UTC', + updated_at: 'Thu, 28 Jul 2022 09:12:07 UTC', + }), + ].join('\n'), + ); const listSubscriptionsEndpoint: MockEndpoint = { url: `${MockRucioServerFactory.RUCIO_HOST}/subscriptions/ddmadmin`, @@ -83,9 +132,9 @@ describe('SubscriptionGateway', () => { headers: { 'Content-Type': 'application/x-json-stream', }, - body: subscriptionStream - } - } + body: subscriptionStream, + }, + }; MockRucioServerFactory.createMockRucioServer(true, [getSubscriptionEndpoint, getSubscriptionByIdEndpoint, listSubscriptionsEndpoint]); }); @@ -109,7 +158,6 @@ describe('SubscriptionGateway', () => { expect(subscription.replication_rules[0].copies).toEqual('*'); expect(subscription.replication_rules[0].lifetime).toEqual(172800); expect(subscription.replication_rules[0].comments).toEqual('Functional tests from Tier-0 to Tier-1s'); - }); it('should stream subscriptions', async () => { @@ -121,20 +169,20 @@ describe('SubscriptionGateway', () => { const subscriptionStream = listSubscriptionsDTO.stream; - if( subscriptionStream == null || subscriptionStream == undefined) { + if (subscriptionStream == null || subscriptionStream == undefined) { fail('Subscription stream is null or undefined'); } - const receivedData: SubscriptionDTO[] = [] + const receivedData: SubscriptionDTO[] = []; const onData = (data: SubscriptionDTO) => { - receivedData.push(data) - } + receivedData.push(data); + }; await new Promise((resolve, reject) => { - subscriptionStream.on('data', onData) - subscriptionStream.on('end', resolve) - subscriptionStream.on('error', reject) + subscriptionStream.on('data', onData); + subscriptionStream.on('end', resolve); + subscriptionStream.on('error', reject); }); expect(receivedData.length).toEqual(3); @@ -142,13 +190,12 @@ describe('SubscriptionGateway', () => { expect(receivedData[0].replication_rules.length).toEqual(1); }); - it("Should list a subscription by Id", async () => { + it('Should list a subscription by Id', async () => { const subscriptionGateway: SubscriptionGatewayOutputPort = appContainer.get(GATEWAYS.SUBSCRIPTION); const subscription = await subscriptionGateway.getById(MockRucioServerFactory.VALID_RUCIO_TOKEN, 'bngjsrfdtlkhugrdgflgiu'); expect(subscription.id).toEqual('bccaabb5877a443abd6c56f3271557df'); expect(subscription.name).toEqual('*Sensitive Data'); expect(subscription.state).toEqual(SubscriptionState.UPDATED); expect(subscription.account).toEqual('ddmadmin'); - }); -}); \ No newline at end of file +}); diff --git a/test/sdk/fixtures/models.ts b/test/sdk/fixtures/models.ts index 36a100458..7933c1904 100644 --- a/test/sdk/fixtures/models.ts +++ b/test/sdk/fixtures/models.ts @@ -1,19 +1,19 @@ -import { BaseDTO } from "@/lib/sdk/dto" -import { AuthenticatedRequestModel, BaseResponseModel } from "@/lib/sdk/usecase-models" -import { BaseViewModel } from "@/lib/sdk/view-models" +import { BaseDTO } from '@/lib/sdk/dto'; +import { AuthenticatedRequestModel, BaseResponseModel } from '@/lib/sdk/usecase-models'; +import { BaseViewModel } from '@/lib/sdk/view-models'; -export type TRequestModel = AuthenticatedRequestModel<{}> +export type TRequestModel = AuthenticatedRequestModel<{}>; export interface TResponseModel extends BaseResponseModel { - message: string + message: string; } export interface StreamDTO extends BaseDTO { - status: 'success' | 'error' - title: string + status: 'success' | 'error'; + title: string; } -export interface ViewModel extends BaseViewModel { - title: string +export interface ViewModel extends BaseViewModel { + title: string; } -export type TDTO = BaseDTO & {message: string} \ No newline at end of file +export type TDTO = BaseDTO & { message: string }; diff --git a/test/sdk/fixtures/pipeline-elements.ts b/test/sdk/fixtures/pipeline-elements.ts index 40c862e3e..a943c649d 100644 --- a/test/sdk/fixtures/pipeline-elements.ts +++ b/test/sdk/fixtures/pipeline-elements.ts @@ -1,89 +1,67 @@ -import { BaseErrorResponseModel, BaseResponseModel } from "@/lib/sdk/usecase-models" -import { BaseStreamingPostProcessingPipelineElement } from "@/lib/sdk/postprocessing-pipeline-elements" -import { TDTO, TRequestModel, TResponseModel } from "./models" +import { BaseErrorResponseModel, BaseResponseModel } from '@/lib/sdk/usecase-models'; +import { BaseStreamingPostProcessingPipelineElement } from '@/lib/sdk/postprocessing-pipeline-elements'; +import { TDTO, TRequestModel, TResponseModel } from './models'; -export class FirstPipelineElement extends BaseStreamingPostProcessingPipelineElement< - TRequestModel, - TResponseModel, - BaseErrorResponseModel, - TDTO -> { - makeGatewayRequest( - requestModel: TRequestModel, - responseModel: TResponseModel, - ): Promise { +export class FirstPipelineElement extends BaseStreamingPostProcessingPipelineElement { + makeGatewayRequest(requestModel: TRequestModel, responseModel: TResponseModel): Promise { const dto: TDTO = { status: 'success', message: 'pipeline element 1', - } - return Promise.resolve(dto) + }; + return Promise.resolve(dto); } validateDTO(dto: TDTO): { - data: TDTO | BaseErrorResponseModel - status: 'success' | 'error' + data: TDTO | BaseErrorResponseModel; + status: 'success' | 'error'; } { return { status: 'success', - data: dto - } + data: dto, + }; } handleGatewayError(error: TDTO): BaseErrorResponseModel { - throw new Error('Method not implemented.') + throw new Error('Method not implemented.'); } - transformResponseModel( - responseModel: TResponseModel, - dto: TDTO, - ): TResponseModel { - const message = responseModel.message + ' ' + dto.message + ' transformed ' + transformResponseModel(responseModel: TResponseModel, dto: TDTO): TResponseModel { + const message = responseModel.message + ' ' + dto.message + ' transformed '; const transformedResponse: TResponseModel = { status: 'success', message: message, - } - return transformedResponse + }; + return transformedResponse; } } -export class SecondPipelineElement extends BaseStreamingPostProcessingPipelineElement< - TRequestModel, - TResponseModel, - BaseErrorResponseModel, - TDTO -> { - makeGatewayRequest( - requestModel: TRequestModel, - responseModel: TResponseModel, - ): Promise { +export class SecondPipelineElement extends BaseStreamingPostProcessingPipelineElement { + makeGatewayRequest(requestModel: TRequestModel, responseModel: TResponseModel): Promise { const dto: TDTO = { status: 'success', message: 'pipeline element 2', - } - return Promise.resolve(dto) + }; + return Promise.resolve(dto); } validateDTO(dto: TDTO): { - data: TDTO | BaseErrorResponseModel - status: 'success' | 'error' + data: TDTO | BaseErrorResponseModel; + status: 'success' | 'error'; } { return { status: 'success', - data: dto - } + data: dto, + }; } handleGatewayError(error: TDTO): BaseErrorResponseModel { - throw new Error('Method not implemented.') + throw new Error('Method not implemented.'); } - transformResponseModel( - responseModel: TResponseModel, - dto: TDTO, - ): TResponseModel { - const message = responseModel.message + dto.message + ' transformed' + transformResponseModel(responseModel: TResponseModel, dto: TDTO): TResponseModel { + const message = responseModel.message + dto.message + ' transformed'; const transformedResponse: TResponseModel = { status: 'success', message: message, - } - return transformedResponse + }; + return transformedResponse; } } diff --git a/test/sdk/fixtures/presenter.ts b/test/sdk/fixtures/presenter.ts index da517fbea..1a6eacc6c 100644 --- a/test/sdk/fixtures/presenter.ts +++ b/test/sdk/fixtures/presenter.ts @@ -1,41 +1,35 @@ -import { BaseStreamingPresenter } from "@/lib/sdk/presenter" -import { BaseErrorResponseModel, BaseResponseModel } from "@/lib/sdk/usecase-models" -import { TResponseModel, ViewModel } from "./models" +import { BaseStreamingPresenter } from '@/lib/sdk/presenter'; +import { BaseErrorResponseModel, BaseResponseModel } from '@/lib/sdk/usecase-models'; +import { TResponseModel, ViewModel } from './models'; -export class TestPresenter extends BaseStreamingPresenter< - BaseResponseModel, - BaseErrorResponseModel, - ViewModel - > { - streamErrorModelToViewModel(error: BaseErrorResponseModel): ViewModel { - const viewModel: ViewModel = { +export class TestPresenter extends BaseStreamingPresenter { + streamErrorModelToViewModel(error: BaseErrorResponseModel): ViewModel { + const viewModel: ViewModel = { + status: 'error', + title: 'failed: ' + error.message, + }; + return viewModel; + } + + constructor(response: any) { + super(response); + } + convertErrorModelToViewModel(errorModel: BaseErrorResponseModel): { + status: number; + viewModel: ViewModel; + } { + return { + status: errorModel.code || 500, + viewModel: { status: 'error', - title: 'failed: ' + error.message, - } - return viewModel - } - - constructor(response: any) { - super(response) - } - convertErrorModelToViewModel(errorModel: BaseErrorResponseModel): { - status: number - viewModel: ViewModel - } { - return { - status: errorModel.code || 500, - viewModel: { - status: 'error', - title: 'failed: ' + errorModel.message, - }, - } - } - streamResponseModelToViewModel( - responseModel: TResponseModel, - ): ViewModel { - return { - status: 'success', - title: 'success: ' + responseModel.message, - } - } - } \ No newline at end of file + title: 'failed: ' + errorModel.message, + }, + }; + } + streamResponseModelToViewModel(responseModel: TResponseModel): ViewModel { + return { + status: 'success', + title: 'success: ' + responseModel.message, + }; + } +} diff --git a/test/sdk/jest.sdk.setup.ts b/test/sdk/jest.sdk.setup.ts index c7d8f3641..3cd2de122 100644 --- a/test/sdk/jest.sdk.setup.ts +++ b/test/sdk/jest.sdk.setup.ts @@ -1,5 +1,5 @@ -import '@testing-library/jest-dom/extend-expect' -import "reflect-metadata" -import fetchMock from 'jest-fetch-mock' -import "@inrupt/jest-jsdom-polyfills" -fetchMock.enableMocks() +import '@testing-library/jest-dom/extend-expect'; +import 'reflect-metadata'; +import fetchMock from 'jest-fetch-mock'; +import '@inrupt/jest-jsdom-polyfills'; +fetchMock.enableMocks(); diff --git a/test/sdk/post-processing-pipeline/multicall-usecase-sync.test.ts b/test/sdk/post-processing-pipeline/multicall-usecase-sync.test.ts index 3b48c70aa..7539fa6e0 100644 --- a/test/sdk/post-processing-pipeline/multicall-usecase-sync.test.ts +++ b/test/sdk/post-processing-pipeline/multicall-usecase-sync.test.ts @@ -1,209 +1,186 @@ -import { BaseDTO } from '@/lib/sdk/dto' -import { BasePostProcessingPipelineElement } from '@/lib/sdk/postprocessing-pipeline-elements' -import { BasePresenter } from '@/lib/sdk/presenter' -import { BaseSingleEndpointPostProcessingPipelineUseCase } from '@/lib/sdk/usecase' -import { - BaseErrorResponseModel, - BaseResponseModel, -} from '@/lib/sdk/usecase-models' -import { BaseViewModel } from '@/lib/sdk/view-models' -import { NextApiResponse } from 'next' -import { createHttpMocks } from 'test/fixtures/http-fixtures' - -type RequestModel = {} -type DTO = BaseDTO & { message: string } +import { BaseDTO } from '@/lib/sdk/dto'; +import { BasePostProcessingPipelineElement } from '@/lib/sdk/postprocessing-pipeline-elements'; +import { BasePresenter } from '@/lib/sdk/presenter'; +import { BaseSingleEndpointPostProcessingPipelineUseCase } from '@/lib/sdk/usecase'; +import { BaseErrorResponseModel, BaseResponseModel } from '@/lib/sdk/usecase-models'; +import { BaseViewModel } from '@/lib/sdk/view-models'; +import { NextApiResponse } from 'next'; +import { createHttpMocks } from 'test/fixtures/http-fixtures'; + +type RequestModel = {}; +type DTO = BaseDTO & { message: string }; interface TResponseModel extends BaseResponseModel { - message: string + message: string; } -class FirstPipelineElement extends BasePostProcessingPipelineElement< - RequestModel, - TResponseModel, - BaseErrorResponseModel, - DTO -> { - makeGatewayRequest( - requestModel: RequestModel, - responseModel: TResponseModel, - ): Promise { +class FirstPipelineElement extends BasePostProcessingPipelineElement { + makeGatewayRequest(requestModel: RequestModel, responseModel: TResponseModel): Promise { return Promise.resolve({ status: 'success', message: '_pipeline_element_1', - }) + }); } validateDTO(dto: DTO): { - status: 'error' | 'success' | 'critical' - data: BaseErrorResponseModel | DTO + status: 'error' | 'success' | 'critical'; + data: BaseErrorResponseModel | DTO; } { return { status: 'success', data: dto, - } + }; } handleGatewayError(error: DTO): BaseErrorResponseModel { - throw new Error('Method not implemented.') + throw new Error('Method not implemented.'); } - transformResponseModel( - responseModel: TResponseModel, - dto: DTO, - ): TResponseModel { - responseModel.message = responseModel.message + dto.message + '_transformed' - return responseModel + transformResponseModel(responseModel: TResponseModel, dto: DTO): TResponseModel { + responseModel.message = responseModel.message + dto.message + '_transformed'; + return responseModel; } } -class ErrorPipelineElement extends BasePostProcessingPipelineElement< - RequestModel, - TResponseModel, - BaseErrorResponseModel, - DTO -> { +class ErrorPipelineElement extends BasePostProcessingPipelineElement { makeGatewayRequest(requestModel: RequestModel, responseModel: TResponseModel): Promise { return Promise.resolve({ status: 'error', errorCode: 401, errorType: 'gateway_endpoint_error', errorMessage: 'Failed to authenticate user', - } as DTO) + } as DTO); } handleGatewayError(error: DTO): BaseErrorResponseModel { - throw new Error('Method not implemented.') + throw new Error('Method not implemented.'); } transformResponseModel(responseModel: TResponseModel, dto: DTO): TResponseModel | BaseErrorResponseModel { - throw new Error('Method not implemented.') + throw new Error('Method not implemented.'); } - } class TestPresenter extends BasePresenter { convertResponseModelToViewModel(responseModel: TResponseModel): { viewModel: BaseViewModel; status: number } { return { viewModel: { - status: "success", + status: 'success', message: responseModel.message, }, status: 200, - } + }; } convertErrorModelToViewModel(errorModel: BaseErrorResponseModel): { viewModel: BaseViewModel; status: number } { return { viewModel: { - status: "error", + status: 'error', message: errorModel.message, }, status: errorModel.code, - } + }; } } class TestMultiCallUseCase extends BaseSingleEndpointPostProcessingPipelineUseCase< RequestModel, TResponseModel, BaseErrorResponseModel, - BaseDTO & { message: string }> { - + BaseDTO & { message: string } +> { constructor(presenter: BasePresenter) { - const firstPipelineElement = new FirstPipelineElement() - super(presenter, [firstPipelineElement]) + const firstPipelineElement = new FirstPipelineElement(); + super(presenter, [firstPipelineElement]); } validateFinalResponseModel(responseModel: TResponseModel): { isValid: boolean; errorModel?: BaseErrorResponseModel | undefined } { return { isValid: true, - } + }; } validateRequestModel(requestModel: RequestModel): BaseErrorResponseModel | undefined { - return undefined + return undefined; } makeGatewayRequest(requestModel: RequestModel): Promise { return Promise.resolve({ status: 'success', message: 'root_element', - }) + }); } handleGatewayError(error: BaseDTO): BaseErrorResponseModel { - throw new Error('Method not implemented.') + throw new Error('Method not implemented.'); } processDTO(dto: DTO): { data: TResponseModel | BaseErrorResponseModel; status: 'success' | 'error' } { const responseModel: TResponseModel = { status: 'success', message: dto.message, - } + }; return { data: responseModel, status: 'success', - } + }; } - } class TestErrorPipelineUseCase extends BaseSingleEndpointPostProcessingPipelineUseCase< -RequestModel, -TResponseModel, -BaseErrorResponseModel, -BaseDTO & { message: string }> { - -constructor(presenter: BasePresenter) { - const firstPipelineElement = new FirstPipelineElement() - const errorPipelineElement = new ErrorPipelineElement() - super(presenter, [firstPipelineElement, errorPipelineElement]) -} + RequestModel, + TResponseModel, + BaseErrorResponseModel, + BaseDTO & { message: string } +> { + constructor(presenter: BasePresenter) { + const firstPipelineElement = new FirstPipelineElement(); + const errorPipelineElement = new ErrorPipelineElement(); + super(presenter, [firstPipelineElement, errorPipelineElement]); + } -validateFinalResponseModel(responseModel: TResponseModel): { isValid: boolean; errorModel?: BaseErrorResponseModel | undefined } { - return { - isValid: true, + validateFinalResponseModel(responseModel: TResponseModel): { isValid: boolean; errorModel?: BaseErrorResponseModel | undefined } { + return { + isValid: true, + }; + } + validateRequestModel(requestModel: RequestModel): BaseErrorResponseModel | undefined { + return undefined; } -} -validateRequestModel(requestModel: RequestModel): BaseErrorResponseModel | undefined { - return undefined -} -makeGatewayRequest(requestModel: RequestModel): Promise { - return Promise.resolve({ - status: 'success', - message: 'root_element', - }) -} + makeGatewayRequest(requestModel: RequestModel): Promise { + return Promise.resolve({ + status: 'success', + message: 'root_element', + }); + } -handleGatewayError(error: BaseDTO): BaseErrorResponseModel { - throw new Error('Method not implemented.') -} -processDTO(dto: DTO): { data: TResponseModel | BaseErrorResponseModel; status: 'success' | 'error' } { - const responseModel: TResponseModel = { - status: 'success', - message: dto.message, + handleGatewayError(error: BaseDTO): BaseErrorResponseModel { + throw new Error('Method not implemented.'); } - return { - data: responseModel, - status: 'success', + processDTO(dto: DTO): { data: TResponseModel | BaseErrorResponseModel; status: 'success' | 'error' } { + const responseModel: TResponseModel = { + status: 'success', + message: dto.message, + }; + return { + data: responseModel, + status: 'success', + }; } } - -} describe('BaseMultiCallStreamableUseCase', () => { - it('Should pass', async () => { - const { req, res, session } = await createHttpMocks() - const useCase = new TestMultiCallUseCase(new TestPresenter(res as unknown as NextApiResponse)) - await useCase.execute({}) - const response = res._getJSONData() + const { req, res, session } = await createHttpMocks(); + const useCase = new TestMultiCallUseCase(new TestPresenter(res as unknown as NextApiResponse)); + await useCase.execute({}); + const response = res._getJSONData(); expect(response).toEqual({ status: 'success', message: 'root_element_pipeline_element_1_transformed', - }) - }) + }); + }); it('Should fail', async () => { - const { req, res, session } = await createHttpMocks() - const useCase = new TestErrorPipelineUseCase(new TestPresenter(res as unknown as NextApiResponse)) - await useCase.execute({}) - const statusCode = res._getStatusCode() - expect(statusCode).toEqual(401) - const response = res._getJSONData() + const { req, res, session } = await createHttpMocks(); + const useCase = new TestErrorPipelineUseCase(new TestPresenter(res as unknown as NextApiResponse)); + await useCase.execute({}); + const statusCode = res._getStatusCode(); + expect(statusCode).toEqual(401); + const response = res._getJSONData(); expect(response).toEqual({ status: 'error', message: 'Failed to authenticate user', - }) - }) -}) + }); + }); +}); diff --git a/test/sdk/post-processing-streaming-pipeline/multicall-usecase-final-validation-error.test.ts b/test/sdk/post-processing-streaming-pipeline/multicall-usecase-final-validation-error.test.ts index 719e28d08..f708253b9 100644 --- a/test/sdk/post-processing-streaming-pipeline/multicall-usecase-final-validation-error.test.ts +++ b/test/sdk/post-processing-streaming-pipeline/multicall-usecase-final-validation-error.test.ts @@ -1,14 +1,14 @@ -import { BaseStreamableDTO } from "@/lib/sdk/dto"; -import { BaseSingleEndpointPostProcessingPipelineStreamingUseCase } from "@/lib/sdk/usecase"; -import { BaseErrorResponseModel } from "@/lib/sdk/usecase-models"; -import { BaseViewModel } from "@/lib/sdk/view-models"; -import { TRequestModel, TResponseModel, StreamDTO, TDTO } from "../fixtures/models"; -import { FirstPipelineElement, SecondPipelineElement } from "../fixtures/pipeline-elements"; -import { TestPresenter } from "../fixtures/presenter"; -import { Readable } from "stream"; -import { MockHttpStreamableResponseFactory } from "test/fixtures/http-fixtures"; +import { BaseStreamableDTO } from '@/lib/sdk/dto'; +import { BaseSingleEndpointPostProcessingPipelineStreamingUseCase } from '@/lib/sdk/usecase'; +import { BaseErrorResponseModel } from '@/lib/sdk/usecase-models'; +import { BaseViewModel } from '@/lib/sdk/view-models'; +import { TRequestModel, TResponseModel, StreamDTO, TDTO } from '../fixtures/models'; +import { FirstPipelineElement, SecondPipelineElement } from '../fixtures/pipeline-elements'; +import { TestPresenter } from '../fixtures/presenter'; +import { Readable } from 'stream'; +import { MockHttpStreamableResponseFactory } from 'test/fixtures/http-fixtures'; -describe("Post Processing Streaming Pipeline Error Handling", () => { +describe('Post Processing Streaming Pipeline Error Handling', () => { class TestErrorInPipilineElementUseCase extends BaseSingleEndpointPostProcessingPipelineStreamingUseCase< TRequestModel, TResponseModel, @@ -17,21 +17,20 @@ describe("Post Processing Streaming Pipeline Error Handling", () => { StreamDTO, BaseViewModel > { - constructor(response: any) { - const firstPipelineElement = new FirstPipelineElement() - const secondPipelineElement = new SecondPipelineElement() - const presenter = new TestPresenter(response) - super(presenter, [firstPipelineElement, secondPipelineElement]) + const firstPipelineElement = new FirstPipelineElement(); + const secondPipelineElement = new SecondPipelineElement(); + const presenter = new TestPresenter(response); + super(presenter, [firstPipelineElement, secondPipelineElement]); } - - validateRequestModel(requestModel: { rucioAuthToken: string; }): BaseErrorResponseModel | undefined { + + validateRequestModel(requestModel: { rucioAuthToken: string }): BaseErrorResponseModel | undefined { return undefined; } - async intializeRequest(request: { rucioAuthToken: string; }): Promise { + async intializeRequest(request: { rucioAuthToken: string }): Promise { return undefined; } - makeGatewayRequest(requestModel: { rucioAuthToken: string; }): Promise { + makeGatewayRequest(requestModel: { rucioAuthToken: string }): Promise { const mockDTOs: StreamDTO[] = [ { status: 'success', @@ -41,76 +40,76 @@ describe("Post Processing Streaming Pipeline Error Handling", () => { status: 'success', title: 'root_element_2', }, - ] + ]; const dto: BaseStreamableDTO = { status: 'success', stream: Readable.from(mockDTOs), - } - return Promise.resolve(dto) + }; + return Promise.resolve(dto); } handleGatewayError(error: BaseStreamableDTO): BaseErrorResponseModel { - throw new Error("Method not implemented."); + throw new Error('Method not implemented.'); } - processStreamedData(dto: StreamDTO): { data: TResponseModel | BaseErrorResponseModel; status: "success" | "error"; } { + processStreamedData(dto: StreamDTO): { data: TResponseModel | BaseErrorResponseModel; status: 'success' | 'error' } { const responseModel: TResponseModel = { status: 'success', message: dto.title, - } + }; return { status: 'success', data: responseModel, - } + }; } - validateFinalResponseModel(responseModel: TResponseModel): { isValid: boolean; errorModel?: BaseErrorResponseModel | undefined; } { + validateFinalResponseModel(responseModel: TResponseModel): { isValid: boolean; errorModel?: BaseErrorResponseModel | undefined } { if (responseModel.message === 'root_element_2 pipeline element 1 transformed pipeline element 2 transformed') { const error: BaseErrorResponseModel = { status: 'error', code: 400, name: 'ValidationError', message: 'Failed to validate response model', - } + }; return { isValid: false, errorModel: error, - } + }; } return { isValid: true, - } + }; } } - it("should stream a Error ViewModel when an error occurs during final validation of response model", async () => { - const res = MockHttpStreamableResponseFactory.getMockResponse() - const useCase = new TestErrorInPipilineElementUseCase(res) + it('should stream a Error ViewModel when an error occurs during final validation of response model', async () => { + const res = MockHttpStreamableResponseFactory.getMockResponse(); + const useCase = new TestErrorInPipilineElementUseCase(res); const requestModel: TRequestModel = { - rucioAuthToken: 'does not matter' - } - - await useCase.execute(requestModel) - const receivedData: any[] = [] + rucioAuthToken: 'does not matter', + }; + + await useCase.execute(requestModel); + const receivedData: any[] = []; const onData = (data: string) => { - receivedData.push(JSON.parse(data)) - } + receivedData.push(JSON.parse(data)); + }; const done = new Promise((resolve, reject) => { - res.on('data', onData) + res.on('data', onData); res.on('end', () => { - res.off('data', onData) - resolve() - }) + res.off('data', onData); + resolve(); + }); res.on('error', err => { - res.off('data', onData) - reject(err) - }) - }) + res.off('data', onData); + reject(err); + }); + }); - await done - console.log(receivedData) - expect (receivedData).toEqual([ + await done; + console.log(receivedData); + expect(receivedData).toEqual([ { status: 'success', title: 'success: root_element_1 pipeline element 1 transformed pipeline element 2 transformed', @@ -118,8 +117,7 @@ describe("Post Processing Streaming Pipeline Error Handling", () => { { status: 'error', title: 'failed: Failed to validate response model', - } - ]) - - }) -}) \ No newline at end of file + }, + ]); + }); +}); diff --git a/test/sdk/post-processing-streaming-pipeline/multicall-usecase-pipeline-errors.test.ts b/test/sdk/post-processing-streaming-pipeline/multicall-usecase-pipeline-errors.test.ts index 89b4e05d1..8c2c6d456 100644 --- a/test/sdk/post-processing-streaming-pipeline/multicall-usecase-pipeline-errors.test.ts +++ b/test/sdk/post-processing-streaming-pipeline/multicall-usecase-pipeline-errors.test.ts @@ -1,37 +1,32 @@ -import { BaseStreamableDTO } from "@/lib/sdk/dto"; -import { BaseStreamingPostProcessingPipelineElement } from "@/lib/sdk/postprocessing-pipeline-elements"; -import { BaseSingleEndpointPostProcessingPipelineStreamingUseCase } from "@/lib/sdk/usecase"; -import { BaseErrorResponseModel } from "@/lib/sdk/usecase-models"; -import { BaseViewModel } from "@/lib/sdk/view-models"; -import { TRequestModel, TResponseModel, StreamDTO, TDTO } from "../fixtures/models"; -import { SecondPipelineElement } from "../fixtures/pipeline-elements"; -import { TestPresenter } from "../fixtures/presenter"; -import { Readable } from "stream"; -import { MockHttpStreamableResponseFactory } from "test/fixtures/http-fixtures"; +import { BaseStreamableDTO } from '@/lib/sdk/dto'; +import { BaseStreamingPostProcessingPipelineElement } from '@/lib/sdk/postprocessing-pipeline-elements'; +import { BaseSingleEndpointPostProcessingPipelineStreamingUseCase } from '@/lib/sdk/usecase'; +import { BaseErrorResponseModel } from '@/lib/sdk/usecase-models'; +import { BaseViewModel } from '@/lib/sdk/view-models'; +import { TRequestModel, TResponseModel, StreamDTO, TDTO } from '../fixtures/models'; +import { SecondPipelineElement } from '../fixtures/pipeline-elements'; +import { TestPresenter } from '../fixtures/presenter'; +import { Readable } from 'stream'; +import { MockHttpStreamableResponseFactory } from 'test/fixtures/http-fixtures'; -describe("Post Processing Streaming Pipeline Error Handling", () => { - class StupidPipelineElement extends BaseStreamingPostProcessingPipelineElement< - TRequestModel, - TResponseModel, - BaseErrorResponseModel, - TDTO> { - makeGatewayRequest(requestModel: { rucioAuthToken: string; }, responseModel: TResponseModel): Promise { +describe('Post Processing Streaming Pipeline Error Handling', () => { + class StupidPipelineElement extends BaseStreamingPostProcessingPipelineElement { + makeGatewayRequest(requestModel: { rucioAuthToken: string }, responseModel: TResponseModel): Promise { return Promise.resolve({ - status: "error", + status: 'error', errorCode: 401, - errorType: "gateway_endpoint_error", - errorMessage: "Failed to authenticate user", + errorType: 'gateway_endpoint_error', + errorMessage: 'Failed to authenticate user', } as TDTO); } - + handleGatewayError(error: TDTO): BaseErrorResponseModel { - throw new Error("Should not be called."); + throw new Error('Should not be called.'); } - + transformResponseModel(responseModel: TResponseModel, dto: TDTO): TResponseModel { - throw new Error("Should not be called."); + throw new Error('Should not be called.'); } - } class TestErrorInPipilineElementUseCase extends BaseSingleEndpointPostProcessingPipelineStreamingUseCase< @@ -42,23 +37,22 @@ describe("Post Processing Streaming Pipeline Error Handling", () => { StreamDTO, BaseViewModel > { - constructor(response: any) { - const errorPipelineElement = new StupidPipelineElement() - const validPipelineElement = new SecondPipelineElement() - const presenter = new TestPresenter(response) - super(presenter, [validPipelineElement, errorPipelineElement]) + const errorPipelineElement = new StupidPipelineElement(); + const validPipelineElement = new SecondPipelineElement(); + const presenter = new TestPresenter(response); + super(presenter, [validPipelineElement, errorPipelineElement]); } - - validateRequestModel(requestModel: { rucioAuthToken: string; }): BaseErrorResponseModel | undefined { + + validateRequestModel(requestModel: { rucioAuthToken: string }): BaseErrorResponseModel | undefined { return undefined; } - async intializeRequest(request: { rucioAuthToken: string; }): Promise { + async intializeRequest(request: { rucioAuthToken: string }): Promise { return undefined; } - - makeGatewayRequest(requestModel: { rucioAuthToken: string; }): Promise { + + makeGatewayRequest(requestModel: { rucioAuthToken: string }): Promise { const mockDTOs: StreamDTO[] = [ { status: 'success', @@ -68,74 +62,73 @@ describe("Post Processing Streaming Pipeline Error Handling", () => { status: 'success', title: 'root_element_2', }, - ] + ]; const dto: BaseStreamableDTO = { status: 'success', stream: Readable.from(mockDTOs), - } - return Promise.resolve(dto) + }; + return Promise.resolve(dto); } handleGatewayError(error: BaseStreamableDTO): BaseErrorResponseModel { - throw new Error("Method not implemented."); + throw new Error('Method not implemented.'); } - processStreamedData(dto: StreamDTO): { data: TResponseModel | BaseErrorResponseModel; status: "success" | "error"; } { + processStreamedData(dto: StreamDTO): { data: TResponseModel | BaseErrorResponseModel; status: 'success' | 'error' } { const responseModel: TResponseModel = { status: 'success', message: dto.title, - } + }; return { status: 'success', data: responseModel, - } + }; } - validateFinalResponseModel(responseModel: TResponseModel): { isValid: boolean; errorModel?: BaseErrorResponseModel | undefined; } { + validateFinalResponseModel(responseModel: TResponseModel): { isValid: boolean; errorModel?: BaseErrorResponseModel | undefined } { // Should be called only once return { isValid: true, - } + }; } } - it("should stream a Error ViewModel when an error occurs in a pipeline element", async () => { - const res = MockHttpStreamableResponseFactory.getMockResponse() - const useCase = new TestErrorInPipilineElementUseCase(res) + it('should stream a Error ViewModel when an error occurs in a pipeline element', async () => { + const res = MockHttpStreamableResponseFactory.getMockResponse(); + const useCase = new TestErrorInPipilineElementUseCase(res); const requestModel: TRequestModel = { - rucioAuthToken: 'does not matter' - } - - await useCase.execute(requestModel) - const receivedData: any[] = [] + rucioAuthToken: 'does not matter', + }; + + await useCase.execute(requestModel); + const receivedData: any[] = []; const onData = (data: string) => { - receivedData.push(JSON.parse(data)) - } + receivedData.push(JSON.parse(data)); + }; const done = new Promise((resolve, reject) => { - res.on('data', onData) + res.on('data', onData); res.on('end', () => { - res.off('data', onData) - resolve() - }) + res.off('data', onData); + resolve(); + }); res.on('error', err => { - res.off('data', onData) - reject(err) - }) - }) + res.off('data', onData); + reject(err); + }); + }); - await done - console.log(receivedData) - expect (receivedData).toEqual([ + await done; + console.log(receivedData); + expect(receivedData).toEqual([ { status: 'error', title: 'failed: Failed to authenticate user', }, { status: 'error', - title: 'failed: Failed to authenticate user' + title: 'failed: Failed to authenticate user', }, - ]) - - }) -}) \ No newline at end of file + ]); + }); +}); diff --git a/test/sdk/post-processing-streaming-pipeline/multicall-usecase.test.ts b/test/sdk/post-processing-streaming-pipeline/multicall-usecase.test.ts index a4fd1d212..9325a14f1 100644 --- a/test/sdk/post-processing-streaming-pipeline/multicall-usecase.test.ts +++ b/test/sdk/post-processing-streaming-pipeline/multicall-usecase.test.ts @@ -1,19 +1,13 @@ -import { BaseStreamableDTO } from '@/lib/sdk/dto' -import { BaseSingleEndpointPostProcessingPipelineStreamingUseCase } from '@/lib/sdk/usecase' -import { - BaseErrorResponseModel, - BaseResponseModel, -} from '@/lib/sdk/usecase-models' -import { BaseStreamingPostProcessingPipelineElement } from '@/lib/sdk/postprocessing-pipeline-elements' -import { Readable, Transform, PassThrough } from 'stream' -import { MockHttpStreamableResponseFactory } from 'test/fixtures/http-fixtures' -import { TRequestModel as TRequestModel, StreamDTO, TResponseModel } from '../fixtures/models' -import { - FirstPipelineElement, - SecondPipelineElement, -} from '../fixtures/pipeline-elements' -import { TestPresenter } from '../fixtures/presenter' -import { BaseViewModel } from '@/lib/sdk/view-models' +import { BaseStreamableDTO } from '@/lib/sdk/dto'; +import { BaseSingleEndpointPostProcessingPipelineStreamingUseCase } from '@/lib/sdk/usecase'; +import { BaseErrorResponseModel, BaseResponseModel } from '@/lib/sdk/usecase-models'; +import { BaseStreamingPostProcessingPipelineElement } from '@/lib/sdk/postprocessing-pipeline-elements'; +import { Readable, Transform, PassThrough } from 'stream'; +import { MockHttpStreamableResponseFactory } from 'test/fixtures/http-fixtures'; +import { TRequestModel as TRequestModel, StreamDTO, TResponseModel } from '../fixtures/models'; +import { FirstPipelineElement, SecondPipelineElement } from '../fixtures/pipeline-elements'; +import { TestPresenter } from '../fixtures/presenter'; +import { BaseViewModel } from '@/lib/sdk/view-models'; describe('BaseMultiCallStreamableUseCase', () => { class TestMultiCallPipelineUseCase extends BaseSingleEndpointPostProcessingPipelineStreamingUseCase< @@ -24,28 +18,22 @@ describe('BaseMultiCallStreamableUseCase', () => { StreamDTO, BaseViewModel > { - - constructor(response: any) { - const firstPipelineElement = new FirstPipelineElement() - const secondPipelineElement = new SecondPipelineElement() - const presenter = new TestPresenter(response) - super(presenter, [firstPipelineElement, secondPipelineElement]) + const firstPipelineElement = new FirstPipelineElement(); + const secondPipelineElement = new SecondPipelineElement(); + const presenter = new TestPresenter(response); + super(presenter, [firstPipelineElement, secondPipelineElement]); } - validateRequestModel( - requestModel: TRequestModel, - ): BaseErrorResponseModel | undefined { - return undefined + validateRequestModel(requestModel: TRequestModel): BaseErrorResponseModel | undefined { + return undefined; } async intializeRequest(request: { rucioAuthToken: string }): Promise { - return undefined + return undefined; } - makeGatewayRequest(requestModel: { - rucioAuthToken: string - }): Promise { + makeGatewayRequest(requestModel: { rucioAuthToken: string }): Promise { const mockDTOs: StreamDTO[] = [ { status: 'success', @@ -55,82 +43,78 @@ describe('BaseMultiCallStreamableUseCase', () => { status: 'success', title: 'root_element_2', }, - ] + ]; const dto: BaseStreamableDTO = { status: 'success', stream: Readable.from(mockDTOs), - } - return Promise.resolve(dto) + }; + return Promise.resolve(dto); } handleGatewayError(error: BaseStreamableDTO): BaseErrorResponseModel { - throw new Error('Method not implemented.') + throw new Error('Method not implemented.'); } - processStreamedData(dto: StreamDTO): { - data: TResponseModel | BaseErrorResponseModel - status: 'success' | 'error' + data: TResponseModel | BaseErrorResponseModel; + status: 'success' | 'error'; } { const responseModel: TResponseModel = { status: 'success', message: dto.title, - } + }; return { status: 'success', data: responseModel, - } + }; } - validateFinalResponseModel(responseModel: BaseResponseModel): { - isValid: boolean - errorModel?: BaseErrorResponseModel | undefined + isValid: boolean; + errorModel?: BaseErrorResponseModel | undefined; } { - const isValid = responseModel.status === 'success' + const isValid = responseModel.status === 'success'; const errorModel: BaseErrorResponseModel = { code: 400, name: 'Validation Error', status: 'error', message: 'responseModel is not valid', - } + }; return { isValid: isValid, errorModel: isValid ? undefined : errorModel, - } + }; } - - } it('should execute successfully', async () => { - const res = MockHttpStreamableResponseFactory.getMockResponse() - const useCase = new TestMultiCallPipelineUseCase(res) + const res = MockHttpStreamableResponseFactory.getMockResponse(); + const useCase = new TestMultiCallPipelineUseCase(res); const requestModel: TRequestModel = { rucioAuthToken: 'does-not-matter', - } + }; - await useCase.execute(requestModel) + await useCase.execute(requestModel); - const receivedData: any[] = [] + const receivedData: any[] = []; const onData = (data: string) => { - receivedData.push(JSON.parse(data)) - } + receivedData.push(JSON.parse(data)); + }; const done = new Promise((resolve, reject) => { - res.on('data', onData) + res.on('data', onData); res.on('end', () => { - res.off('data', onData) - resolve() - }) + res.off('data', onData); + resolve(); + }); res.on('error', err => { - res.off('data', onData) - reject(err) - }) - }) + res.off('data', onData); + reject(err); + }); + }); - await done + await done; expect(receivedData).toEqual([ { status: 'success', @@ -140,67 +124,58 @@ describe('BaseMultiCallStreamableUseCase', () => { status: 'success', title: 'success: root_element_2 pipeline element 1 transformed pipeline element 2 transformed', }, - ]) - }) + ]); + }); class Validator extends Transform { constructor() { - super({ objectMode: true }) + super({ objectMode: true }); } - _transform( - chunk: any, - encoding: BufferEncoding, - callback: (error?: Error, data?: any) => void, - ): void { - console.log('validating chunk: ' + chunk) - this.push(chunk) - callback() + _transform(chunk: any, encoding: BufferEncoding, callback: (error?: Error, data?: any) => void): void { + console.log('validating chunk: ' + chunk); + this.push(chunk); + callback(); } } it('tests piping', async () => { - const baseStream = Readable.from(['root_element_1', 'root_element_2']) + const baseStream = Readable.from(['root_element_1', 'root_element_2']); - const firstPipelineElement = new PassThrough({ objectMode: true }) - const secondPipelineElement = new PassThrough({ objectMode: true }) - const validator = new Validator() + const firstPipelineElement = new PassThrough({ objectMode: true }); + const secondPipelineElement = new PassThrough({ objectMode: true }); + const validator = new Validator(); const res = new Transform({ objectMode: true, transform: (chunk, encoding, callback) => { - console.log('transforming chunk: ' + chunk) - callback(undefined, chunk) + console.log('transforming chunk: ' + chunk); + callback(undefined, chunk); }, - }) - - baseStream - .on('error', error => console.log(error)) - .pipe(firstPipelineElement) - firstPipelineElement - .on('error', error => console.log(error)) - .pipe(secondPipelineElement) - secondPipelineElement.pipe(validator) - validator.on('error', error => console.log(error)).pipe(res) - - const receivedData: string[] = [] + }); + + baseStream.on('error', error => console.log(error)).pipe(firstPipelineElement); + firstPipelineElement.on('error', error => console.log(error)).pipe(secondPipelineElement); + secondPipelineElement.pipe(validator); + validator.on('error', error => console.log(error)).pipe(res); + + const receivedData: string[] = []; const onData = (data: string) => { - receivedData.push(data.toString()) - } + receivedData.push(data.toString()); + }; const done = new Promise((resolve, reject) => { - res.on('data', onData) + res.on('data', onData); res.on('end', () => { - res.off('data', onData) - resolve() - }) + res.off('data', onData); + resolve(); + }); res.on('error', err => { - res.off('data', onData) - reject(err) - }) - }) + res.off('data', onData); + reject(err); + }); + }); - await done + await done; - expect(receivedData).toEqual(['root_element_1', 'root_element_2']) - }) - -}) + expect(receivedData).toEqual(['root_element_1', 'root_element_2']); + }); +}); diff --git a/test/sdk/stream-error-handling.test.ts b/test/sdk/stream-error-handling.test.ts index 2fb7ea5f4..79d0c8b2b 100644 --- a/test/sdk/stream-error-handling.test.ts +++ b/test/sdk/stream-error-handling.test.ts @@ -1,35 +1,41 @@ -import { BaseStreamableDTO } from "@/lib/sdk/dto"; -import { BaseSingleEndpointStreamingUseCase } from "@/lib/sdk/usecase"; -import { BaseErrorResponseModel } from "@/lib/sdk/usecase-models"; -import { BaseViewModel } from "@/lib/sdk/view-models"; -import { MockHttpStreamableResponseFactory } from "test/fixtures/http-fixtures"; -import MockRucioServerFactory from "test/fixtures/rucio-server"; -import { TRequestModel, StreamDTO, TResponseModel, ViewModel } from "./fixtures/models"; -import { TestPresenter } from "./fixtures/presenter"; -import { Readable } from "stream"; +import { BaseStreamableDTO } from '@/lib/sdk/dto'; +import { BaseSingleEndpointStreamingUseCase } from '@/lib/sdk/usecase'; +import { BaseErrorResponseModel } from '@/lib/sdk/usecase-models'; +import { BaseViewModel } from '@/lib/sdk/view-models'; +import { MockHttpStreamableResponseFactory } from 'test/fixtures/http-fixtures'; +import MockRucioServerFactory from 'test/fixtures/rucio-server'; +import { TRequestModel, StreamDTO, TResponseModel, ViewModel } from './fixtures/models'; +import { TestPresenter } from './fixtures/presenter'; +import { Readable } from 'stream'; - -describe("Stream Error Handling", () => { - class TestStreamErrorUseCase extends BaseSingleEndpointStreamingUseCase { - async intializeRequest(request: { rucioAuthToken: string; }): Promise { +describe('Stream Error Handling', () => { + class TestStreamErrorUseCase extends BaseSingleEndpointStreamingUseCase< + TRequestModel, + TResponseModel, + BaseErrorResponseModel, + BaseStreamableDTO, + StreamDTO, + BaseViewModel + > { + async intializeRequest(request: { rucioAuthToken: string }): Promise { return undefined; } - + constructor(response: any) { - const presenter = new TestPresenter(response) + const presenter = new TestPresenter(response); super(presenter); } - validateRequestModel(requestModel: { rucioAuthToken: string; }): BaseErrorResponseModel | undefined { + validateRequestModel(requestModel: { rucioAuthToken: string }): BaseErrorResponseModel | undefined { return undefined; } - makeGatewayRequest(requestModel: { rucioAuthToken: string; }): Promise { - if(requestModel.rucioAuthToken !== MockRucioServerFactory.VALID_RUCIO_TOKEN){ + makeGatewayRequest(requestModel: { rucioAuthToken: string }): Promise { + if (requestModel.rucioAuthToken !== MockRucioServerFactory.VALID_RUCIO_TOKEN) { return Promise.resolve({ - status: "error", - errorType: "gateway_endpoint_error", + status: 'error', + errorType: 'gateway_endpoint_error', errorCode: 401, - errorMessage: "Failed to authenticate user", + errorMessage: 'Failed to authenticate user', stream: null, }); } @@ -46,87 +52,86 @@ describe("Stream Error Handling", () => { status: 'error', title: 'invalid', errorCode: 400, - } - ] + }, + ]; return Promise.resolve({ - status: "success", + status: 'success', code: 200, - stream: Readable.from(mockDTOs) + stream: Readable.from(mockDTOs), }); } handleGatewayError(error: BaseStreamableDTO): BaseErrorResponseModel { - throw new Error("Method not implemented."); + throw new Error('Method not implemented.'); } - processStreamedData(dto: StreamDTO): { data: TResponseModel | BaseErrorResponseModel; status: "success" | "error"; } { - if(dto.title === "invalid"){ + processStreamedData(dto: StreamDTO): { data: TResponseModel | BaseErrorResponseModel; status: 'success' | 'error' } { + if (dto.title === 'invalid') { return { data: { code: 400, - name: "Not Found", - status: "error", - message: "Failed to process data" + name: 'Not Found', + status: 'error', + message: 'Failed to process data', }, - status: "error" - } + status: 'error', + }; } return { data: { - status: "success", - message: dto.title + status: 'success', + message: dto.title, }, - status: "success" - } + status: 'success', + }; } - } - it("Should return an error ViewModel for request made to stream endpoint", async () => { - const res = MockHttpStreamableResponseFactory.getMockResponse() - const useCase = new TestStreamErrorUseCase(res) + it('Should return an error ViewModel for request made to stream endpoint', async () => { + const res = MockHttpStreamableResponseFactory.getMockResponse(); + const useCase = new TestStreamErrorUseCase(res); const requestModel: TRequestModel = { rucioAuthToken: 'does-not-matter', - } + }; - await useCase.execute(requestModel) + await useCase.execute(requestModel); - expect(res.statusCode).toBe(401) - const errorViewModel: ViewModel = await JSON.parse(res._getData()) - expect(errorViewModel.status).toBe('error') - expect(errorViewModel.title).toBe('failed: Failed to authenticate user') - }) + expect(res.statusCode).toBe(401); + const errorViewModel: ViewModel = await JSON.parse(res._getData()); + expect(errorViewModel.status).toBe('error'); + expect(errorViewModel.title).toBe('failed: Failed to authenticate user'); + }); - it("Should return an error ViewModel for individual stream elements that are invalid", async () => { - const res = MockHttpStreamableResponseFactory.getMockResponse() - const useCase = new TestStreamErrorUseCase(res) + it('Should return an error ViewModel for individual stream elements that are invalid', async () => { + const res = MockHttpStreamableResponseFactory.getMockResponse(); + const useCase = new TestStreamErrorUseCase(res); const requestModel: TRequestModel = { rucioAuthToken: MockRucioServerFactory.VALID_RUCIO_TOKEN, - } + }; - await useCase.execute(requestModel) + await useCase.execute(requestModel); - const receivedData: any[] = [] + const receivedData: any[] = []; const onData = (data: string) => { - receivedData.push(JSON.parse(data)) - } + receivedData.push(JSON.parse(data)); + }; const done = new Promise((resolve, reject) => { - res.on('data', onData) + res.on('data', onData); res.on('end', () => { - res.off('data', onData) - resolve() - }) + res.off('data', onData); + resolve(); + }); res.on('error', err => { - res.off('data', onData) - reject(err) - }) - }) - await done - expect(receivedData.length).toBe(3) - expect(receivedData[2].status).toBe('error') - expect(receivedData[2].title).toBe('failed: Failed to process data') - }) -}); \ No newline at end of file + res.off('data', onData); + reject(err); + }); + }); + await done; + expect(receivedData.length).toBe(3); + expect(receivedData[2].status).toBe('error'); + expect(receivedData[2].title).toBe('failed: Failed to process data'); + }); +}); diff --git a/test/sdk/streaming-transformers.test.ts b/test/sdk/streaming-transformers.test.ts index 367993fdf..cfd04e6a4 100644 --- a/test/sdk/streaming-transformers.test.ts +++ b/test/sdk/streaming-transformers.test.ts @@ -1,186 +1,156 @@ -import appContainer from "@/lib/infrastructure/ioc/container-config" -import {NewlineDelimittedDataParser} from "@/lib/sdk/stream-transformers" -import {Transform} from "stream" - +import appContainer from '@/lib/infrastructure/ioc/container-config'; +import { NewlineDelimittedDataParser } from '@/lib/sdk/stream-transformers'; +import { Transform } from 'stream'; class TestPipelineSink extends Transform { - _transform(chunk: any, encoding: string, callback: Function) { - const data = chunk.toString() - this.push(data) - callback() + const data = chunk.toString(); + this.push(data); + callback(); } - } class TestPipelineSource extends Transform { - _transform(chunk: any, encoding: string, callback: Function) { - const data = chunk.toString() - this.push(data) - callback() + const data = chunk.toString(); + this.push(data); + callback(); } - } // Is double parsing a desired behaviour? -const parseChunk = (chunk: string) => JSON.parse(JSON.parse(chunk)) +const parseChunk = (chunk: string) => JSON.parse(JSON.parse(chunk)); -describe("NewlineDelimittedDataParser - a transform stream that parses newline-delimited JSON data", () => { +describe('NewlineDelimittedDataParser - a transform stream that parses newline-delimited JSON data', () => { let source: Transform; let sink: Transform; let outputChunks: string[]; beforeEach(() => { - source = new TestPipelineSource() - sink = new TestPipelineSink() - outputChunks = [] + source = new TestPipelineSource(); + sink = new TestPipelineSink(); + outputChunks = []; - sink.on('data', (chunk) => { - outputChunks.push(chunk.toString()) - }) + sink.on('data', chunk => { + outputChunks.push(chunk.toString()); + }); - source.pipe(new NewlineDelimittedDataParser()).pipe(sink) - }) + source.pipe(new NewlineDelimittedDataParser()).pipe(sink); + }); - it("Handles a single full NDJSON object in one chunk", () => { - source.write('{"hello": "world"}\n') + it('Handles a single full NDJSON object in one chunk', () => { + source.write('{"hello": "world"}\n'); - const parsedChunks = outputChunks.map(parseChunk) - expect(parsedChunks).toEqual([ - {'hello': 'world'} - ]) - }) + const parsedChunks = outputChunks.map(parseChunk); + expect(parsedChunks).toEqual([{ hello: 'world' }]); + }); - it("Handles two full NDJSON objects in one chunk", () => { - source.write('{"hello": "world"}\n{"test": "json"}\n') + it('Handles two full NDJSON objects in one chunk', () => { + source.write('{"hello": "world"}\n{"test": "json"}\n'); - const parsedChunks = outputChunks.map(parseChunk) - expect(parsedChunks).toEqual([ - {'hello': 'world'}, - {'test': 'json'}, - ]) - }) + const parsedChunks = outputChunks.map(parseChunk); + expect(parsedChunks).toEqual([{ hello: 'world' }, { test: 'json' }]); + }); - it("Handles multiple full NDJSON objects in one chunk", () => { - source.write('{"hello": "world"}\n{"test": "json"}\n{"variable": 0, "test": "json"}\n{"variable": 0}\n') + it('Handles multiple full NDJSON objects in one chunk', () => { + source.write('{"hello": "world"}\n{"test": "json"}\n{"variable": 0, "test": "json"}\n{"variable": 0}\n'); - const parsedChunks = outputChunks.map(parseChunk) - expect(parsedChunks).toEqual([ - {'hello': 'world'}, - {'test': 'json'}, - {'test': 'json', 'variable': 0}, - {'variable': 0} - ]) - }) - - it("Handles multiple full NDJSON objects in two chunks", () => { - source.write('{"hello": "world"}\n{"test": "json"}\n') - source.write('{"variable": 0, "test": "json"}\n') - - const parsedChunks = outputChunks.map(parseChunk) - expect(parsedChunks).toEqual([ - {'hello': 'world'}, - {'test': 'json'}, - {'test': 'json', 'variable': 0}, - ]) - }) - - it("Handles multiple full NDJSON objects in three chunks", () => { - source.write('{"hello": "world"}\n{"test": "json"}\n') - source.write('{"variable": 0, "test": "json"}\n') - source.write('{"variable": 0}\n{"hello": "world", "variable": 0}\n') - - const parsedChunks = outputChunks.map(parseChunk) + const parsedChunks = outputChunks.map(parseChunk); + expect(parsedChunks).toEqual([{ hello: 'world' }, { test: 'json' }, { test: 'json', variable: 0 }, { variable: 0 }]); + }); + + it('Handles multiple full NDJSON objects in two chunks', () => { + source.write('{"hello": "world"}\n{"test": "json"}\n'); + source.write('{"variable": 0, "test": "json"}\n'); + + const parsedChunks = outputChunks.map(parseChunk); + expect(parsedChunks).toEqual([{ hello: 'world' }, { test: 'json' }, { test: 'json', variable: 0 }]); + }); + + it('Handles multiple full NDJSON objects in three chunks', () => { + source.write('{"hello": "world"}\n{"test": "json"}\n'); + source.write('{"variable": 0, "test": "json"}\n'); + source.write('{"variable": 0}\n{"hello": "world", "variable": 0}\n'); + + const parsedChunks = outputChunks.map(parseChunk); expect(parsedChunks).toEqual([ - {'hello': 'world'}, - {'test': 'json'}, - {'test': 'json', 'variable': 0}, - {'variable': 0}, - {'hello': 'world', 'variable': 0}, - ]) - }) + { hello: 'world' }, + { test: 'json' }, + { test: 'json', variable: 0 }, + { variable: 0 }, + { hello: 'world', variable: 0 }, + ]); + }); it("Doesn't pass a partial NDJSON", () => { - source.write('{"hello": "world"') + source.write('{"hello": "world"'); - expect(outputChunks.length).toEqual(0) - }) + expect(outputChunks.length).toEqual(0); + }); - it("Handles a single NDJSON passed in two chunks", () => { - source.write('{"hello": "world"') - source.write('}\n') + it('Handles a single NDJSON passed in two chunks', () => { + source.write('{"hello": "world"'); + source.write('}\n'); - const parsedChunks = outputChunks.map(parseChunk) - expect(parsedChunks).toEqual([ - {'hello': 'world'} - ]) - }) - - it("Handles a single NDJSON passed in multiple chunks", () => { - source.write('{"hel') - source.write('lo": "') - source.write('wor') - source.write('ld"}') - source.write('\n') - - const parsedChunks = outputChunks.map(parseChunk) - expect(parsedChunks).toEqual([ - {'hello': 'world'} - ]) - }) + const parsedChunks = outputChunks.map(parseChunk); + expect(parsedChunks).toEqual([{ hello: 'world' }]); + }); - it("Handles multiple NDJSON passed partially", () => { - source.write('{"hello": "wor') - source.write('ld"}\n{"test": "json"}\n{"variable"') - source.write(': 0}\n') + it('Handles a single NDJSON passed in multiple chunks', () => { + source.write('{"hel'); + source.write('lo": "'); + source.write('wor'); + source.write('ld"}'); + source.write('\n'); - const parsedChunks = outputChunks.map(parseChunk) - expect(parsedChunks).toEqual([ - {'hello': 'world'}, - {'test': 'json'}, - {'variable': 0}, - ]) - }) - - it("Handles long chunks of full NDJSON objects", () => { - source.write('{"hello": "world"}\n{"test": "json"}\n{"hour": 1}\n') - source.write('{"variable": 0, "test": "json"}\n{"method": "GET"}\n') - source.write('{"variable": 0}\n{"hello": "world", "variable": 0}\n{"error": "unknown"}\n') - - const parsedChunks = outputChunks.map(parseChunk) + const parsedChunks = outputChunks.map(parseChunk); + expect(parsedChunks).toEqual([{ hello: 'world' }]); + }); + + it('Handles multiple NDJSON passed partially', () => { + source.write('{"hello": "wor'); + source.write('ld"}\n{"test": "json"}\n{"variable"'); + source.write(': 0}\n'); + + const parsedChunks = outputChunks.map(parseChunk); + expect(parsedChunks).toEqual([{ hello: 'world' }, { test: 'json' }, { variable: 0 }]); + }); + + it('Handles long chunks of full NDJSON objects', () => { + source.write('{"hello": "world"}\n{"test": "json"}\n{"hour": 1}\n'); + source.write('{"variable": 0, "test": "json"}\n{"method": "GET"}\n'); + source.write('{"variable": 0}\n{"hello": "world", "variable": 0}\n{"error": "unknown"}\n'); + + const parsedChunks = outputChunks.map(parseChunk); expect(parsedChunks).toEqual([ - {'hello': 'world'}, - {'test': 'json'}, - {'hour': 1}, - {'test': 'json', 'variable': 0}, - {'method': 'GET'}, - {'variable': 0}, - {'hello': 'world', 'variable': 0}, - {'error': 'unknown'} - ]) - }) + { hello: 'world' }, + { test: 'json' }, + { hour: 1 }, + { test: 'json', variable: 0 }, + { method: 'GET' }, + { variable: 0 }, + { hello: 'world', variable: 0 }, + { error: 'unknown' }, + ]); + }); it("Doesn't pass a chunk that doesn't end in a newline", () => { - source.write('{"hello": "world"}') + source.write('{"hello": "world"}'); - expect(outputChunks.length).toEqual(0) - }) + expect(outputChunks.length).toEqual(0); + }); it("Doesn't pass a chunk that isn't a valid NDJSON string", () => { - source.write('abc\n') + source.write('abc\n'); - expect(outputChunks.length).toEqual(0) - }) + expect(outputChunks.length).toEqual(0); + }); - it("Passes only valid NDJSON strings", () => { - source.write('{"hello": "wor') - source.write('ld"}\n{{"test": "json"}\n{"variable": 0}\n') + it('Passes only valid NDJSON strings', () => { + source.write('{"hello": "wor'); + source.write('ld"}\n{{"test": "json"}\n{"variable": 0}\n'); - const parsedChunks = outputChunks.map(parseChunk) - expect(parsedChunks).toEqual([ - {'hello': 'world'}, - {'variable': 0}, - ]) - }) -}) \ No newline at end of file + const parsedChunks = outputChunks.map(parseChunk); + expect(parsedChunks).toEqual([{ hello: 'world' }, { variable: 0 }]); + }); +});