diff --git a/src/routes/relay/relay.controller.module.ts b/src/routes/relay/relay.controller.module.ts index dd0514fb70..b75730f445 100644 --- a/src/routes/relay/relay.controller.module.ts +++ b/src/routes/relay/relay.controller.module.ts @@ -2,10 +2,11 @@ import { Module } from '@nestjs/common'; import { RelayDomainModule } from '@/domain/relay/relay.domain.module'; import { RelayService } from '@/routes/relay/relay.service'; import { RelayController } from '@/routes/relay/relay.controller'; +import { RelayLegacyController } from '@/routes/relay/relay.legacy.controller'; @Module({ imports: [RelayDomainModule], providers: [RelayService], - controllers: [RelayController], + controllers: [RelayController, RelayLegacyController], }) export class RelayControllerModule {} diff --git a/src/routes/relay/relay.legacy.controller.spec.ts b/src/routes/relay/relay.legacy.controller.spec.ts new file mode 100644 index 0000000000..7f0d43f1ed --- /dev/null +++ b/src/routes/relay/relay.legacy.controller.spec.ts @@ -0,0 +1,87 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import * as request from 'supertest'; +import { AppModule } from '@/app.module'; +import { CacheModule } from '@/datasources/cache/cache.module'; +import { TestCacheModule } from '@/datasources/cache/__tests__/test.cache.module'; +import configuration from '@/config/entities/__tests__/configuration'; +import { RequestScopedLoggingModule } from '@/logging/logging.module'; +import { TestLoggingModule } from '@/logging/__tests__/test.logging.module'; +import { NetworkModule } from '@/datasources/network/network.module'; +import { TestNetworkModule } from '@/datasources/network/__tests__/test.network.module'; +import { TestAppProvider } from '@/__tests__/test-app.provider'; +import { AccountDataSourceModule } from '@/datasources/account/account.datasource.module'; +import { TestAccountDataSourceModule } from '@/datasources/account/__tests__/test.account.datasource.module'; +import { INestApplication } from '@nestjs/common'; +import { faker } from '@faker-js/faker'; + +describe('Relay controller', () => { + let app: INestApplication; + const supportedChainIds = Object.keys(configuration().relay.apiKey); + + beforeEach(async () => { + jest.resetAllMocks(); + + const defaultConfiguration = configuration(); + const testConfiguration = (): typeof defaultConfiguration => ({ + ...defaultConfiguration, + features: { + ...defaultConfiguration.features, + relay: true, + }, + }); + + const moduleFixture: TestingModule = await Test.createTestingModule({ + imports: [AppModule.register(testConfiguration)], + }) + .overrideModule(AccountDataSourceModule) + .useModule(TestAccountDataSourceModule) + .overrideModule(CacheModule) + .useModule(TestCacheModule) + .overrideModule(RequestScopedLoggingModule) + .useModule(TestLoggingModule) + .overrideModule(NetworkModule) + .useModule(TestNetworkModule) + .compile(); + + app = await new TestAppProvider().provide(moduleFixture); + await app.init(); + }); + + afterAll(async () => { + await app.close(); + }); + + describe('POST /v1/chains/:chainId/relay', () => { + it('should return 302 and redirect to the new endpoint', async () => { + const chainId = faker.helpers.arrayElement(supportedChainIds); + const safeAddress = faker.finance.ethereumAddress(); + const data = faker.string.hexadecimal(); + + await request(app.getHttpServer()) + .post(`/v1/relay/${chainId}`) + .send({ + to: safeAddress, + data, + }) + .expect(308) + .expect((res) => { + expect(res.get('location')).toBe('/v1/chains/:chainId/relay'); + }); + }); + }); + describe('GET /v1/relay/:chainId/:safeAddress', () => { + it('should return 302 and redirect to the new endpoint', async () => { + const chainId = faker.string.numeric(); + const safeAddress = faker.finance.ethereumAddress(); + + await request(app.getHttpServer()) + .get(`/v1/relay/${chainId}/${safeAddress}`) + .expect(301) + .expect((res) => { + expect(res.get('location')).toBe( + '/v1/chains/:chainId/relay/:safeAddress', + ); + }); + }); + }); +}); diff --git a/src/routes/relay/relay.legacy.controller.ts b/src/routes/relay/relay.legacy.controller.ts new file mode 100644 index 0000000000..a541c46a99 --- /dev/null +++ b/src/routes/relay/relay.legacy.controller.ts @@ -0,0 +1,18 @@ +import { Controller, Post, Redirect, Get, HttpStatus } from '@nestjs/common'; + +@Controller({ + version: '1', + path: 'relay/:chainId', +}) +export class RelayLegacyController { + @Post() + @Redirect('/v1/chains/:chainId/relay', HttpStatus.PERMANENT_REDIRECT) + relay(): void {} + + @Get(':safeAddress') + @Redirect( + '/v1/chains/:chainId/relay/:safeAddress', + HttpStatus.MOVED_PERMANENTLY, + ) + getRelaysRemaining(): void {} +}